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


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

文章插图
 
假设有表tb_sku,其表结构如下 。
 
MySQL 原理与优化:Limit 查询优化

文章插图
【MySQL 原理与优化:Limit 查询优化】 
表中大约有200w条记录,执行如下的sql 语句大约 4.36s 返回数据
select count(*) from tb_sku;
 
MySQL 原理与优化:Limit 查询优化

文章插图
 
 
接着我们使用 对其进行分页查询:
select * from tb_sku limit 0,10;
limit 语句 其中0 代表起始位置,10 为每页返回的数据数量 。
MySQL 原理与优化:Limit 查询优化

文章插图
 
 
如上图所示,很快就返回了查询结果 。
接着我们再使用SQL 语句
select * from tb_sku limit 10,10;
语句从记录位置10的位置开始再往下返回10 条记录,也就是第二页的信息 。其返回时间也是比较快 。
然后,我们加大起始位置 到100w如下,
select * from tb_sku limit 1000000,10;
 
MySQL 原理与优化:Limit 查询优化

文章插图
 
 
此时返回时间需要0.74 s,这说明了使用limit 对大数据量的表进行分页,位置越靠后效率越低 。拿上面的例子来说,limit 会先对 100w 的数据进行排序,然后再返回10 条数据,而且仅仅返回100w 到 100w 零10条 的记录,其他查询的记录都会丢弃掉,这种做法查询排序的代价非常大 。
由此我们需要对大数据量表进行limit 操作进行优化,官方给出的方案是通过覆盖索引和子查询的方式进行优化
根据这个思路首先对id 进行查询
select id from tb_sku order by id limit 1000000,10;
 
MySQL 原理与优化:Limit 查询优化

文章插图
 
 
查询结果就只需要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;
 
MySQL 原理与优化:Limit 查询优化

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




    推荐阅读