内容概要

利用主索引提升SQL的查询效率是我们经常使用的一个技巧,但是有些时候MySQL给出的执行计划却完全出乎我们的意料,我们预想MySQL会通过索引扫描完成查询,但是MySQL给出的执行计划却是通过全表扫描完成查询的,其中的某些场景我们可以利用覆盖索引进行优化。

前些天,有个同事跟我说:“我写了个SQL,SQL很简单,但是查询速度很慢,并且针对查询条件创建了索引,然而索引却不起作用,你帮我看看有没有办法优化?”。

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

优化前的表结构、数据量、SQL、执行计划、执行时间

表结构

CREATE TABLE `t_order` (

`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,

`order_code` char(12) NOT NULL,

`order_amount` decimal(12,2) NOT NULL,

PRIMARY KEY (`id`),

UNIQUE KEY `uni_order_code` (`order_code`) USING BTREE )

ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

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

数据量:316977

这个数据量还是比较小的,不过如果SQL足够差,一样会查询很慢。

SQL

select order_code,

order_amount from t_order order by order_code limit 1000;

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

执行计划

全表扫描、文件排序,注定查询慢!

那为什么MySQL没有利用索引(uni_order_code)扫描完成查询呢?因为MySQL认为这个场景利用索引扫描并非最优的结果。我们先来看下执行时间,然后再来分析为什么没有利用索引扫描。

执行时间:260ms

的确,执行时间太长了,如果表数据量继续增长下去,性能会越来越差。

全表扫描、文件排序与索引扫描、索引排序的区别

全表扫描、文件排序:

虽然是全表扫描,但是扫描是顺序的(不管机械硬盘还是SSD顺序读写性能都是高的),并且数据量不是特别大,所以这部分消耗的时间应该不是特别大,主要的消耗应该是在排序上。

利用索引扫描、利用索引顺序:

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

根据我们自己的分析选择全表扫描相对更优。如果把limit 1000改成limit 10,则执行计划会完全不一样。

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

有,覆盖索引。

优化后的索引、执行计划、执行时间

创建索引

ALTER TABLE `t_order`

ADD INDEX `idx_ordercode_orderamount` USING BTREE (`order_code` ASC, `order_amount` ASC);

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

执行计划

执行计划显示查询会利用覆盖索引,并且只扫描了1000行数据,查询的性能应该是非常好的。

执行时间:13ms

从执行时间来看,SQL的执行时间提升到原来的1/20,已经达到我们的预期。

总结

覆盖索引是select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖。索引的字段不只包含查询列,还包含查询条件、排序等。

要写出性能很好的SQL不仅需要学习SQL,还要能看懂数据库执行计划,了解数据库执行过程、索引的数据结构等。

转载自:Mr船长

原文:https://my.oschina.net/loujinhe/blog/1528233#comment-list

相关阅读:

远程数据库的表超过20个索引的影响

如何理解并正确使用MySql索引

CBO对于Cost值相同索引的选择

Oracle索引分支块的结构

复合索引与绑定变量

资源下载

关注公众号:数据和云(OraNews)回复关键字获取

‘2017DTC’,2017DTC大会PPT

‘DBALIFE’,“DBA的一天”海报

‘DBA04’,DBA手记4经典篇章电子书

‘INTERNALS’,Oracle RAC PPT

‘122ARCH’,Oracle 12.2体系结构图

‘2017OOW’,Oracle OpenWorld资料

‘PRELECTION’,大讲堂讲师课程资料

MySQL SQL优化之覆盖索引相关推荐

  1. mysql覆盖索引解决模糊查询失效_关于MySQL的SQL优化之覆盖索引

    前些天,有个同事跟我说:"我写了个SQL,SQL很简单,但是查询速度很慢,并且针对查询条件创建了索引,然而索引却不起作用,你帮我看看有没有办法优化?". 我对他提供的case进行了 ...

  2. mysql sql优化书籍_MySQL SQL优化的正确姿势

    大家好,我是知数堂SQL 优化班老师 网名:骑龟的兔子 已经很久没写文章了 今天分享一篇优化SQL 案例 slow query 里有如下 SQL 看下执行计划如下 从执行计划可以看出C表全表扫描了 那 ...

  3. MySQL SQL 优化参数 引发的悲剧

    大家好,我是知数堂SQL 优化班老师 网名:骑龟的兔子 今天给大家看一个案例来讨论,这个案例是真实案例,因为之前踩bug 导致数据库crash 所以临时关了优化器参数 set gloabl optim ...

  4. SQL优化之组合索引中字段的顺序

    SQL优化之组合索引中字段的顺序 记一次SQL优化:组合索引中字段顺序有讲究,越离散的字段越靠前,哪个列可以降低索引扫描成本放在前面. Refer:https://blog.csdn.net/pan_ ...

  5. MySQL回表与覆盖索引

    MySQL回表与覆盖索引 1. MySQL存储引擎 2. MySQL索引结构 2.1 B树和B+树定义 2.2 B树和B+树区别 2.3 B+Tree优点 3. MySQL索引回表 4. MySQL覆 ...

  6. mysql优化之覆盖索引

    覆盖索引 1.当发起一个被索引覆盖的查询时,在explain的extra列可以看到using index的信息,此时就使用了覆盖索引 mysql> explain select store_id ...

  7. mysql sql优化_浅谈mysql中sql优化

    说到sql优化,一般有几个步骤呢,在网上看到了一篇很不错的帖子.在这分享一下吧,也是自己学习的一个过程. 一.查找慢查询 1.1.查看SQL执行频率 SHOW STATUS LIKE 'Com_%'; ...

  8. mysql sql优化_MySQL数据库SQL语句优化原理专题(三)

    需求 做过开发的同学,对分页肯定不会陌生,因为很多前台页面展示,为了更好的展示数据,就会用到分页,所以如何写一个高性能的分页SQL语句,是每一个开发人员需要掌握的技能. 分页SQL 这里给大家写一个分 ...

  9. mysql sql优化_MySQL优化SQL语句的步骤

    我们在执行一条SQL语句的时候,如果我们想要知道这条SQL语句查询了哪些表,有没有使用索引,获取数据的时候遍历了多少行数据,我们可以通过EXPLAIN命令来查看这些执行信息,这些执行信息统称为执行计划 ...

最新文章

  1. 3D人体姿态估计--Coarse-to-Fine Volumetric Prediction for Single-Image 3D Human Pose
  2. Oracle创建表空间(转)
  3. 第6章-一阶多智体系统一致性-->6.5 带有领航者系统一致性
  4. Ajax学习整理笔记
  5. springboot数据访问基本操作步骤
  6. 从0学习css开发之 font-size的基本用法
  7. 还有必要吗?iPhone 11系列终于要全家族支持双卡双待了
  8. 代码整洁之道(二)优雅注释之道
  9. 11. SpringMVC拦截器(资源和权限管理)
  10. c mysql主从复制_Mysql 主从复制
  11. 海康威视设备发现sdp原理
  12. 什么是TCP粘包?怎么解决TCP粘包问题?
  13. 中创软件哪个部分是外包_什么是外包| 第2部分
  14. 动态规划之最长回文子串
  15. jave-1.0.2免费领取
  16. GVIM/VIM常用快捷操作(更新中)
  17. Hackthebox:Granny Walkthrough(not use metasploit)
  18. 2022.11.7-复制粘贴代码带来的问题
  19. KEBA 控制器通过 NT50 连接西门子 PLC
  20. http三次握手_【吊打面试,击中要害】http三次握手四次挥手,https证书验证阶段和数据传输阶段...

热门文章

  1. 怎么成为开源贡献者_成为负责任的开源用户
  2. (67)Vue-cli 项目搭建
  3. Vue笔记大融合总结
  4. 深度学习笔记(12) Batch归一化网络
  5. linux 串口 read 超时,请教linux串口问题!read读取时buf里只读取到8的倍数?
  6. java 不加锁_在java中,在高并发的时候,不加锁的时候。
  7. 基于新版 node 的 vue 脚手架搭建
  8. 2018年广东工业大学文远知行杯新生程序设计竞赛 1007 活在无尽梦境的后续 β...
  9. [转]Postgres-XL 10r1英文文档
  10. redis内存模型及应用解读