不说话,先贴代码
public PageResultgetLargeList(BaseCondition baseCondition) {
PageResult result=new PageResult();
Session session= this.getSessionFactory().getCurrentSession();
StringBuilder conditionStr=newStringBuilder();
conditionStr.append("");if(baseCondition.getParamSql()!=null)conditionStr.append(baseCondition.getParamSql());
conditionStr.append(" order by "+baseCondition.getOrder()+" "+baseCondition.getSort());
conditionStr.append(" limit ");
conditionStr.append((Integer.parseInt(baseCondition
.getPage())- 1)*Integer.parseInt(baseCondition.getRows()));
conditionStr.append(",");
conditionStr.append(Integer.parseInt(baseCondition.getRows()));
String sql="select id from Bo_Tmc_Raw where 1=1 "+conditionStr.toString();
SQLQuery q=session.createSQLQuery(sql);
q.addScalar("id",Hibernate.LONG);
List ids =q.list();
String idstr="";for(Long item:ids){
idstr=idstr+item+",";
}if(ids.size()!=0)idstr=idstr.substring(0,idstr.length()-1);
sql="from BoTmcRaw where id in("+idstr+")";
Query ql=session.createQuery(sql);
result.setList(ql.list());
SQLQuery qc= session.createSQLQuery("select count(id) from bo_tmc_raw where 1=1 "+baseCondition.getParamSql());
result.setCount(((BigInteger)qc.uniqueResult()).intValue());returnresult;
}
众所周知啊,mysql是轻量级的数据库,有很多功能是他不具备的。造句挺难的,别嫌我啰嗦,这个查询分页,其实很早我就注意到了,只是一直没有机会搞。
mysql是有查询分页功能的,limit这个关键字有人不知道,这个一点也不奇怪,但是当你认识他的时候,幸运的家伙会有好心人告诉你,这个不是真正的分页,mysql服务器还是会把所有的条目都遍历一遍,反正意思就是说,这个limit算法是有问题的,到底是不是这个好心人说的那样,我现在却有点怀疑了。
我们现在再来看看这个,
select * from ooo where id>=(select id from ooo limit 4523,1) limit 0,10;
写完sql加;是个好习惯。
但是。。算了;
这是我刚刚学习的一个语法,他的意思是说,limit算法的速度,取决于第一个参数的大小。第一个数,也就是开始位置越大,这个查询的时间就越长。这一点我刚刚证实是正确的,不做其他讨论。
依据这个语法,我们可以做出比直接使用limit更高效的查询,但是在实际应用中,这个直接拿来用很不好用。所以,这个只能做一个概念模型。
其实原理都是一样的,id作为索引,其查询效率非常高,用id做分页,然后分页得到的id用来做少量的全字段查询。我们要考虑的是,如果再加入排序,顺序倒序,其他字段排序,为什么一定要用大于号?sql里面现成的in关键字怎么不用?不要跟我说什么效率,你一页能显示多少数据?在一页数据中这个效率问题是可以忽略不计的。无论如何,比你手动10几20次查询快的多。也有人说用exists,这个语法只能用来关联查询,in是可以拼字符串的,显然比起两个表的关联查询,还是分开查比较好。
目前这个结果还算不错,大约70万条数据左右吧,第一页是瞬间就出来了,然而最后一页还是花了不少时间,可能用where比较好吧。别忘了加索引!索引!索引!重要的事情说三遍!加在id上就行。