内容摘要
使用主索引来提高SQL的查询效率是我们经常使用的技巧,但有时候MySQL给出的执行计划却完全出乎意料。我们期望MySQL通过索引扫描来完成查询,但是MySQL给出的执行计划是通过全表扫描来完成查询的,有些场景可以通过覆盖索引来优化。
前几天有同事跟我说:“我写了一个SQL,很简单,但是查询速度很慢,针对查询条件创建了一个索引,但是索引不起作用。能不能帮我看看有没有办法优化一下?”。
我优化了他提供的案例,整理了优化流程。
优化前的表结构、数据量、SQL、执行计划、执行时间
表结构
CREATE TABLE `t_order `(
` id` bigint(20)无符号非空自动增量,
“订单代码”字符(12)不为空,
`订单_金额`十进制(12,2)非空,
主键(` id '),
唯一键` uni_order_code` (`order_code `)使用BTREE)
ENGINE = Innodb AUTO _ INDEX = 1 DEFAULT CHARSET = ut F8;
隐藏了一些不相关的字段后,我们可以看到表足够简单,在order_code上创建了一个唯一的索引uni _ order_code。
数据量:316977
这个数据量还是比较小的,但是如果SQL足够差,查询会比较慢。
结构化查询语言
选择订单代码,
order _ amount from t _ order order by order _ code limit 1000;
哇,SQL够简单,但有时候越简单越难优化。
实施计划
全表扫描和文件排序注定查询速度慢!
那MySQL为什么不用索引(uni_order_code)扫描来完成查询呢?因为MySQL认为在这种场景下索引扫描并不是最好的结果。我们先看执行时间,再分析为什么不用索引扫描。
执行时间:260毫秒
执行计划显示,查询将使用覆盖索引,只扫描1000行数据,因此查询性能应该很好。
执行时间:13毫秒
在执行时间上,SQL的执行时间增加到了原来的1/20,达到了我们的预期。
摘要
覆盖索引意味着select的数据列只能从索引中获取,而不能读取数据行。换句话说,查询列应该被索引覆盖。索引字段不仅包括查询列,还包括查询条件、排序等。
要写出性能良好的SQL,不仅要学习SQL,还要了解数据库执行计划、数据库执行过程、索引数据结构等等。
转载自:船长先生
原文:https://my.oschina.net/loujinhe/blog/1528233#comment-list
1.《覆盖索引 MySQL SQL优化之覆盖索引》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《覆盖索引 MySQL SQL优化之覆盖索引》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/guoji/673944.html