美文网首页
MySQL优化排序和延迟关联

MySQL优化排序和延迟关联

作者: virusY | 来源:发表于2019-06-20 10:49 被阅读0次

优化排序

我们以 MySQL 官方数据库 employees表来做示例.
employees 表结构:

image.png

数据预览:


image2.png

表中的数据量大概是 30W, 表中现只有一个主键,现有如下一个需求,查询性别为 M (男性)的员工信息,并按照出生日期排序.通常我们会书写以下 sql 语句:

SELECT * FROM employees  WHERE gender="M"  ORDER BY birth_date  LIMIT 30;

消耗时间:

image.png
Explain 结果:
image2.png
由于两个字段都是没有索引的,所以 mysql 执行的事全表扫描,优化器需要通过索引进行回表查询数据(using where),并且进行了排序操作(using filesort),速度较慢.


可以考虑以下优化,由于性别只有男性和女性两个值,所以不考虑单独给性别添加索引,我们可以将性别和出生日期建立一个覆盖索引:
ALTER TABLE employees ADD INDEX gender_birth (gender,birth_date);

再次执行,查看消耗时间:


image3.png

Explain 结果:


image4.png
可以看出,查询速度提升了非常多.这里使用了 mysql 5.6 的新特性Index Condition Pushdown (using index condition),即在数据引擎层就可以利用索引直接判断 where 条件是否成立,无需回表判断,过滤掉大量的无用数据.并且索引中包含了 birth_date,mysql 无需对数据进行排序操作.

延迟关联

考虑如下语句:

SELECT * FROM employees  WHERE gender="M"  ORDER BY birth_date  LIMIT 170000,30;

sql 执行时间:


image.png

这里面是一个很常见的分页业务,但是即使添加了索引,当偏移量越来越大时,查询依旧会很慢,优化这类查询的一个比较好的策略就是延迟关联,通过覆盖索引先查出所需数据的主键,再根据这些主键关联原表获得需要的数据行.
更改 sql:

SELECT * FROM employees INNER JOIN( SELECT emp_no  FROM employees  
WHERE gender = "M"  ORDER BY birth_date  LIMIT 170000,30) AS x USING (emp_no);

执行时间:


image2.png

Explain:


image3.png

相关文章

网友评论

      本文标题:MySQL优化排序和延迟关联

      本文链接:https://www.haomeiwen.com/subject/vafdqctx.html