作家
登录

MySQL SQL优化之覆盖索引

作者: 来源: 2017-09-05 14:06:17 阅读 我要评论

前些天,有个同事跟我说:“我写了个SQL,SQL很简单,然则萌芽速度很慢,并且针对萌芽前提创建了索引,然而索引却不起感化,你帮我看看竽暌剐没有办法优化?”。

我对他供给的case进行了优化,并将优化过程整顿了下来。

我们先来看看竽暌古化前的表构造、数据量、SQL、履行筹划、履行时光等。

1. 表构造:

  1. CREATE TABLE `t_order` ( 
  2.  
  3. `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
  4.  
  5. `order_code` char(12) NOT NULL
  6.  
  7. `order_amount` decimal(12,2) NOT NULL
  8.  
  9. PRIMARY KEY (`id`), 
  10.  
  11. UNIQUE KEY `uni_order_code` (`order_code`) USING BTREE 
  12.  
  13. ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;  

隐蔽了部分不相干字段后,可以看到表足够简单, 并且在order_code上创建了独一性索引uni_order_code。

2. 数据量:316977

这个数据量照样比较小的,不过如不雅SQL足够差,一样会萌芽很慢。

3. SQL:

哇,SQL足够简单,不过有时刻越简单也越难优化。

  1. select order_code, order_amount from t_order order by order_code limit 1000; 

4. 履行筹划:

id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t_order ALL NULL NULL NULL NULL 316350 Using filesort

全表扫描、文件排序,注定萌芽慢!

那为什么MySQL没有应用索引(uni_order_code)扫描完成萌芽呢?因为MySQL认为这个场景应用索引扫描并非最优的结不雅。我们先来看下履行时光,然后再来分析为什么没有应用索引扫描。

我们来看看应用覆盖索引优化后的索引、履行筹划、履行时光。

5. 履行时光:260ms

切实其实,履行时光太长了,如不雅表数据量持续增长下去,机能会越来越差。

1. 全表扫描、文件排序:

2. 应用索引扫描、应用索引次序:

uni_order_code是二级索引,索引上保存了(order_code,id),每扫描一条索引须要根据索引上的id定位(随机IO)到数据行上攫取order_amount,须要1000次随机IO才能完成萌芽,而机械硬盘随机IO的效力是极低的(机械硬盘每秒寻址几百次)。

根据我们本身的分析选择全表扫描相对更优。如不雅把limit 1000改成limit 10,则履行筹划会完全不一样。

既然我们已经知道是因为随机IO导致无法应用索引,那么竽暌剐没有办法清除随机IO呢?

有,覆盖索引。

1. 创建索引:

  1. ALTER TABLE `t_order` 
  2.  
  3. ADD INDEX `idx_ordercode_orderamount` USING BTREE (`order_code` ASC, `order_amount` ASC);  

创建了复合索引idx_ordercode_orderamount(order_code,order_amount),将select的列order_amount也放到索引中。


  推荐阅读

  如何理解马云演讲「十年后没有数据分析师的职业」

结缘:我小我很爱好研究马云的研究,一是认为他把工作做到了弗成思议的高度,二是他很爱对将来思虑场且愿意把结不雅分享。可以或许接触他的思惟,是一件异常荣幸的工作。我踏入数据行业也>>>详细阅读


本文标题:MySQL SQL优化之覆盖索引

地址:http://www.17bianji.com/lsqh/37146.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)