mysql 查询优化

不说话,先贴代码

public PageResult<BoTmcRaw> getLargeList(BaseCondition baseCondition) {
        PageResult<BoTmcRaw> result=new PageResult<BoTmcRaw>();
        Session session = this.getSessionFactory().getCurrentSession();
        StringBuilder conditionStr=new StringBuilder();
        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<Long> 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());
        return result;
    }

 

众所周知啊,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上就行。

posted on 2016-09-23 15:48  ooj88s  阅读(271)  评论(1编辑  收藏  举报