zoukankan      html  css  js  c++  java
  • MYSQL的大数据量情况下的分页查询优化

    最近做的项目需要实现一个分页查询功能,自己先看了别人写的方法:

     1     <!-- 查询 -->
     2     <select id="queryMonitorFolder" parameterType="monitorFolderQuery" resultMap="monitorFolderMap">
     3         select
     4             id, name, type, var_num, erp, createTime, modifyTime
     5         from 
     6             monitor_folder
     7         where
     8             yn = 1
     9         <if test="name != null">
    10             and name like concat('%',#{name,jdbcType=VARCHAR},'%')
    11         </if>
    12         and <![CDATA[id <=]]>
    13         (   select 
    14                 id 
    15             from 
    16                 monitor_folder 
    17             where 
    18                 yn=1 
    19                 <if test="name != null">
    20                     and name like concat('%',#{name,jdbcType=VARCHAR},'%')
    21                 </if>
    22             order by id desc limit #{startRowNum},1)
    23         order by id desc
    24         limit #{pageSize}
    25     </select>

    当时我个人的思路是:在分页中使用了两次查询,效率比较低。直接使用limit就好了。

    查过资料之后,不管是自己的想法还是这个代码都是有不足的。

    limit的标准写法:

    1 SELECT * FROM table  LIMIT [offset,] rows | rows OFFSET offset

    比如要查第十个开始的十个,就是limit 10, 10

    许多网站的分页功能的底层实现就是依赖前端给后端传来一些参数,比如起始页和页面大小,来结合limit控制分页。但是这个地方首先有一个问题:效率。

    如果这么写:

    1 SELECT * FROM student LIMIT 10000 , 10;

    实际底层执行是从第一行开始找到10010行,再抛弃前面的一万行。所以当用户往后翻到很多页的时候,offset这个值可能就比较大,实际执行效率就会很慢。

    一般有几种做法来弥补。

    1,用方法计算出开始和结尾条件,用where语句对查询进行限制。

    1 SELECT * FROM student WHERE ID >= 9990 AND ID <= 9999;

    比如前端传来:pageIndex = 1000, pageSize = 10。 也就是第一千页,每页十条。得到这两个参数之后,直接用方法计算得到需要查询的数据条件:WHERE id >= 9999 AND id <= 9999。

    这样做的显著好处就是速度快并且也很好理解。而显著坏处就是使用限制。什么意思呢,就是说你计算出的这个id的范围不一定能全部命中。一般数据库的删除是修改某个字段表示删除,这样的话你计算的id范围可能就有的记录被删除了,同时,前端可能还传来别的限制条件,比如发帖日期在一个月之内,谁发的帖等等。所以问题的核心就是不能保证计算的范围都能匹配上。如果这里做的比较粗糙(比如后端这么做,前端也直接拿这些数据显示),实际的效果就是用户点开一页,明明显示说10条记录,结果只有5条,而且每一页的情况还不一致。

    2,where语句限制一半,limit控制行数

    1 SELECT * FROM student WHERE ID >= 9990 LIMIT 10;

    这样的好处就是不仅效率高了,而且能刚好拿十条。但是这里依然还是有一个问题:不适用于所有情况。具体不适用与什么情况呢?简单来说就是id和行数不能对应的情况。比如ID本身是无规律离散的,那么计算这个起始ID就不能简单的pageIndex * pageSize了。

      

  • 相关阅读:
    音乐分类/生成杂记
    音视频编码笔记
    《The challenge of realistic music generation: modelling raw audio at scale》论文阅读笔记
    使用基于Caffe的MobileNet分类踩坑备忘录
    四大轻量化模型对比(转)
    WaveNet: 原始音频生成模型
    《SONG FROM PI: A MUSICALLY PLAUSIBLE NETWORK FOR POP MUSIC GENERATION》论文笔记
    上采样 及 Sub-pixel Convolution (子像素卷积)
    python之sys._getframe() 用于查看函数被什么函数调用以及被第几行调用及被调用函数所在文件
    11
  • 原文地址:https://www.cnblogs.com/dsj2016/p/6196609.html
Copyright © 2011-2022 走看看