写点什么

MySQL 原理与优化:Limit 查询优化

作者:崔皓
  • 2022 年 8 月 09 日
    湖北
  • 本文字数:679 字

    阅读完需:约 2 分钟


假设有表 tb_sku,其表结构如下。



表中大约有 200w 条记录,执行如下的 sql 语句大约 4.36s 返回数据

select count(*) from tb_sku;



接着我们使用 对其进行分页查询:

select * from tb_sku limit 0,10;

limit 语句 其中 0 代表起始位置,10 为每页返回的数据数量。


如上图所示,很快就返回了查询结果。

接着我们再使用 SQL 语句

select * from tb_sku limit 10,10;

语句从记录位置 10 的位置开始再往下返回 10 条记录,也就是第二页的信息。其返回时间也是比较快。

然后,我们加大起始位置 到 100w 如下,

select * from tb_sku limit 1000000,10;



此时返回时间需要 0.74 s,这说明了使用 limit 对大数据量的表进行分页,位置越靠后效率越低。拿上面的例子来说,limit 会先对 100w 的数据进行排序,然后再返回 10 条数据,而且仅仅返回 100w 到 100w 零 10 条 的记录,其他查询的记录都会丢弃掉,这种做法查询排序的代价非常大。

由此我们需要对大数据量表进行 limit 操作进行优化,官方给出的方案是通过覆盖索引和子查询的方式进行优化

根据这个思路首先对 id 进行查询

select id from tb_sku order by id limit 1000000,10;



查询结果就只需要 0.34s 比之前的 0.74s 要快多了。究其原因,因为直接返回 id 的信息,并没有进行回表操作,所以速度别 select * 要快

由于我们需要获得 select * 的信息,也就是 tb_user 所有字段的信息,因此需要将上面的查询结果和 tb_user 进行 jion 操作。

select s.* from tb_sku s ,(select id from tb_sku order by id limit 1000000,10 ) t where s.id = t.id;



这里通过查询 id 和子查询 的方式将查询结果缩短为 0.38s,比之前直接通过 select * 的方式要缩短一倍的查询时间。

发布于: 刚刚阅读数: 4
用户头像

崔皓

关注

还未添加个人签名 2019.01.02 加入

还未添加个人简介

评论

发布
暂无评论
MySQL 原理与优化:Limit 查询优化_崔皓_InfoQ写作社区