mysql覆盖索引解决模糊查询失效_关于MySQL的SQL优化之覆盖索引
前些天,有个同事跟我说:“我写了个SQL,SQL很简单,但是查询速度很慢,并且针对查询条件创建了索引,然而索引却不起作用,你帮我看看有没有办法优化?”。
我对他提供的case进行了优化,并将优化过程整理了下来。
我们先来看看优化前的表结构、数据量、SQL、执行计划、执行时间等。
1. 表结构:
CREATETABLE`t_order` (
`id` bigint(20) unsignedNOTNULLAUTO_INCREMENT,
`order_code` char(12)NOTNULL,
`order_amount` decimal(12,2)NOTNULL,
PRIMARYKEY(`id`),
UNIQUEKEY`uni_order_code` (`order_code`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULTCHARSET=utf8;
隐藏了部分不相关字段后,可以看到表足够简单, 并且在order_code上创建了唯一性索引uni_order_code。
2. 数据量:316977
这个数据量还是比较小的,不过如果SQL足够差,一样会查询很慢。
3. SQL:
selectorder_code, order_amountfromt_orderorderbyorder_code limit 1000;
哇,SQL足够简单,不过有时候越简单也越难优化。
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
的确,执行时间太长了,如果表数据量继续增长下去,性能会越来越差。
我们来分析下MySQL为什么使用全表扫描、文件排序,而没有使用索引扫描、利用索引顺序:
1. 全表扫描、文件排序:
虽然是全表扫描,但是扫描是顺序的(不管机械硬盘还是SSD顺序读写性能都是高的),并且数据量不是特别大,所以这部分消耗的时间应该不是特别大,主要的消耗应该是在排序上。
2. 利用索引扫描、利用索引顺序:
uni_order_code是二级索引,索引上保存了(order_code,id),每扫描一条索引需要根据索引上的id定位(随机IO)到数据行上读取order_amount,需要1000次随机IO才能完成查询,而机械硬盘随机IO的效率是极低的(机械硬盘每秒寻址几百次)。
根据我们自己的分析选择全表扫描相对更优。如果把limit 1000改成limit 10,则执行计划会完全不一样。
既然我们已经知道是因为随机IO导致无法利用索引,那么有没有办法消除随机IO呢?
有,覆盖索引。
我们来看看利用覆盖索引优化后的索引、执行计划、执行时间。
1. 创建索引:
ALTERTABLE`t_order`
ADDINDEX`idx_ordercode_orderamount` USING BTREE (`order_code`ASC, `order_amount`ASC);
创建了复合索引idx_ordercode_orderamount(order_code,order_amount),将select的列order_amount也放到索引中。
2. 执行计划:
id
select_type
table
type
possible_keys
key
key_len
ref
rows
Extra
1
SIMPLE
t_order
index
NULL
idx_ordercode_
orderamount
42
NULL
1000
Using index
执行计划显示查询会利用覆盖索引,并且只扫描了1000行数据,查询的性能应该是非常好的。
3. 执行时间:13ms
从执行时间来看,SQL的执行时间提升到原来的1/20,已经达到我们的预期。
总结:
覆盖索引是select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖。索引的字段不只包含查询列,还包含查询条件、排序等。
要写出性能很好的SQL不仅需要学习SQL,还要能看懂数据库执行计划,了解数据库执行过程、索引的数据结构等。
【编辑推荐】
【责任编辑:庞桂玉 TEL:(010)68476606】
点赞 0
mysql覆盖索引解决模糊查询失效_关于MySQL的SQL优化之覆盖索引相关推荐
- MySQL 用全文索引解决模糊查询
点击下方"IT牧场",选择"设为星标" 前言 我们都知道 InnoDB 在模糊查询数据时使用 "%xx" 会导致索引失效,但有时需求就是如此 ...
- mysql模糊查询提速_【MySQL】Mysql模糊查询like提速优化
[MySQL]Mysql模糊查询like提速优化 在使用msyql进行模糊查询的时候,很自然的会用到like语句,通常情况下,在数据量小的时候,不容易看出查询的效率,但在数据量达到百万级,千万级的时候 ...
- mysql中有几种模糊查询?
mysql中有几种模糊查询? 聊起mysql中的模糊查询,大家可能马上就能想到like保留字. like加通配符就能完成很多模糊查询的操作. 比如希望查询出所有以词jet开头的产品 select * ...
- mysql模糊查询单词_你知道什么是 MySQL 的模糊查询?
原标题:你知道什么是 MySQL 的模糊查询? 作者 | luanhz 责编 | 郭芮 本文对MySQL中几种常用的模糊搜索方式进行了介绍,包括LIKE通配符.RegExp正则匹配.内置字符串函数以及 ...
- mysql解决模糊查询包含关系
mysql解决模糊查询包含关系 后台要根据期限筛选查询时如果用like, SELECT * from t_user_accord_invest t where t.invest_period like ...
- mysql查询所有图书信息_PHP+MySQL使用mysql_num_rows实现模糊查询图书信息功能
本文实例讲述了PHP+MySQL使用mysql_num_rows实现模糊查询图书信息功能.分享给大家供大家参考,具体如下: 一.代码 td{ font-size:9pt; } .style2 {col ...
- 解决模糊查询问题 element UI 从服务器搜索数据,输入关键字进行查找
解决模糊查询问题 element UI 从服务器搜索数据,输入关键字进行查找 参考文章: (1)解决模糊查询问题 element UI 从服务器搜索数据,输入关键字进行查找 (2)https://ww ...
- mysql数据库的xml模糊查询
mysql数据库的xml模糊查询 mybatis框架的xml中<= , >=解析会出现问题,编译报错,所以需要转译 正常的是使用%xxxx% ,现在需要使用 concat('%',#{xx ...
- 利用php实现图书查询功能,PHP+MySQL使用mysql_num_rows实现模糊查询图书信息功能
本文实例讲述了php+mysql使用mysql_num_rows实现模糊查询图书信息功能.分享给大家供大家参考,具体如下: 一.代码 td{ font-size:9pt; } .style2 {col ...
最新文章
- 二数和,三数和,四数和的优化总结
- 简单动态规划问题分析
- dynamodb java_使用Java查询DynamoDB项
- 在网络虚拟化之前部署NFV将使运营商网络面临风险
- 软件测试中一个BUG的生命周期
- python识别简单训练模型_Python-OpenCV —— 物体识别(TrainCascadeClassification)
- 【雷达通信】基于matlab联邦滤波算法惯性+GPS+地磁组合导航仿真【含Matlab源码 1276期】
- 攀枝花学院计算机专业单身率,重磅 | 攀枝花学院2018届毕业生就业质量年度报告...
- 在xp中运行 .air 文件--Adobe AIR Runtime for Window
- Kettle(Pentaho Data Integration) 下载安装使用介绍/功能汇总
- CAM350 V14.6 检查gerber文件
- VSCode配置html文件自动补全(语法提示)
- bcdedit无法打开启
- 关于Intel酷睿(Core)品牌CPU的不同系列和不同代产品间的性能差异知识普及
- 汶川地震亲历者:唯有经历过惊惶失策,才不至于“花容失色
- 2012云计算发展趋势
- visual basic与python_学visual basic还是 python?
- c语言添加删除课程的思路,基于C语言实现学生选课系统
- LTE学习笔记:OFDM
- android 仿微视,腾讯微视和抖音一样?模仿还是照搬?