zoukankan      html  css  js  c++  java
  • 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上就行。

  • 相关阅读:
    vim编辑器和bash算术运算入门
    vim编辑器
    egrep及文本处理工具
    grep与基本正则表达式
    bash脚本编程基础及配置文件
    博客开通了
    测试用例考虑因素
    地图测试点的总结
    app测试的case点(2)
    App 99.9%稳定
  • 原文地址:https://www.cnblogs.com/ooj88s/p/5900304.html
Copyright © 2011-2022 走看看