MySQL性能优化_limit 的优化

MySQL_2_性能优化

    • 2. 如何优化 limit 100W ?
      • 1) limit 存在的问题
      • 2) limit 为什么会存在这样的问题?
      • 3) 第一次优化——自增索引
      • 4) 第二次优化——条件查询转化为基于主键id的查询
      • 5) 第三次优化——条件查询转化为基于主键id的查询 + inner join

2. 如何优化 limit 100W ?

mysql limit 性能优化
求求你别再用offset和limit分页了

1) limit 存在的问题

需求:在一个存有 1 亿条数据的表中,分别执行如下分页查询,观察查询所用时间;

select * from emp limit 1000000,10;
select * from emp limit 10,10;

MySQL性能优化_limit 的优化_第1张图片
MySQL性能优化_limit 的优化_第2张图片
可以看到,同样是分页查询,limit 1000000 和 limit 10 性能相差巨大,差不多在 1000 倍以上;

2) limit 为什么会存在这样的问题?

为什么数据偏移量变大之后 limit 操作会变慢?这需要从 limit 的执行原理说起,以如下语句为例,其执行过程如下:

select * from emp limit 1000000,10;

这条 SQL 的执行过程如下:

  1. 从数据表中读取第 N 条数据添加到数据集中;
  2. 重复第一步直到 N=1000000 + 10;
  3. 根据 offset 丢弃前面的 1000000 条数据;
  4. 返回剩余的 10 条数据;

可以发现,数据库在进行 limit 操作时,必须先查询出对应数量的数据,而数据量越大,数据库的查询时间也会越长;

3) 第一次优化——自增索引

利用自增索引,将 limit 分页操作中的全表扫描转化为范围扫描,可以有效的缩短分页查询时间,sql 如下:

select * from emp limit 1000000,10;
select * from emp where id >= 1000000 limit 10;

MySQL性能优化_limit 的优化_第3张图片
MySQL性能优化_limit 的优化_第4张图片
可以看到,这种优化方式明显的缩短了 limit 分页的查询时间,对于包含 1 亿条数据的数据表而言,时间差距在千倍以上;

但是,这种方式存在如下缺点:

  • 数据表必须包含自增索引,而且自增索引的的数据还必须是连续的;
  • 不可在 where 关键字后添加其他查询条件,否则会导致查询含义发生改变;

因此,对 limit 进行自增索引列的优化可能不太符合实际开发需求;

4) 第二次优化——条件查询转化为基于主键id的查询

利用子查询,将原来基于 ename 的搜索转化为基于主键 id 的搜索;
利用 id 是主键索引的特性,加快查询速度;

select * from emp where ename='svZLER' limit 1000000,10;
select * from emp where id in (select id from emp where ename='eMxdWz') limit 1000000,10;

MySQL性能优化_limit 的优化_第5张图片
可以看到,对于含有 1 亿条数据的数据表而言,带条件进行 limit 分页时,条件查询转化为基于主键id的查询后,差不多比普通条件查询快了 6s 左右,也明显的加快了查询速度;

但是,需要注意,in 关键字本身有 1000 条数据量的限制,而且,在数据量变大之后,in 本身也会存在效率的问题;因此,该优化方式也不是最理想的优化方式;

5) 第三次优化——条件查询转化为基于主键id的查询 + inner join

既然 in 关键字存在 1000 数据量的限制以及本身效率的问题,所以,使用 inner join 代替 in 操作进行优化;

select * from emp where ename='svZLER' limit 1000000,10;
select * from emp where id in (select id from emp where ename='eMxdWz') limit 1000000,10;
select * from emp inner join (select id from emp where ename='eMxdWz' limit 1000000,10) b using(id);

MySQL性能优化_limit 的优化_第6张图片
可以看到,使用 inner join 进行优化之后,查询速度相比 in 的方式快了差不多 7s,相比普通条件查询快了差不多 14s;使用 inner join 进行 limit 分页优化是比较理想的方式;

你可能感兴趣的:(MySQL,mysql,性能优化,数据库)