MySQL索引优化(二)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MySQL索引优化(二)

MySQL索引优化(二)


一、演示索引失效问题


(1)先建立一个staffs表,往其中插入三条数据,其中id为自增的主键


2020021511404819.png

(2)在name,age,pos字段上建立复合索引:


ALTER TABLE staffs ADD INDEX idx_staffs_nameAgePos(name,age,pos);


(3)现在先列出一些常见的引起索引失效的原因:


1.全值匹配我最爱:


EXPLAIN SELECT * FROM staffs WHERE name='July';


结果如下:

20200215133733729.png

EXPLAIN SELECT * FROM staffs WHERE name='July' AND age=25;

20200215142918623.png


EXPLAIN SELECT * FROM staffs WHERE name='July' AND age=25 AND pos='dev';


20200215144653814.png


以上三个都是ok的


然而,以下语句却变成了全表扫描,没有用到索引


EXPLAIN SELECT * FROM staffs WHERE age=25 AND pos='dev';

20200215145029157.png


EXPLAIN SELECT * FROM staffs WHERE pos='dev';


2020021514514040.png


根据这几个分析,可以引申出下面的结论:


2.最佳左前缀法则


如果索引了多列,要遵守最左前缀法则,指的是查询从索引最左列开始并且不跳过索引中的列

EXPLAIN SELECT * FROM staffs WHERE name='July' AND age=25 AND pos='dev';

20200215152418542.png


上述SQL语句索引未失效,因此可以得出个口诀“排头大哥不能死,中间兄弟不能断”,即索引的第一个列必须要用到,才能确保索引不失效;中间的列不要断开,否则用不到全部的索引。


3.不在索引列上做任何操作(计算、函数、自动或手动类型转换),否则会导致索引失效而转向全表扫描。


如:

EXPLAIN SELECT * FROM staffs WHERE LEFT(name,4)='July';

20200215153404713.png


显然,在索引列上添加了操作后,性能下降了。


4.存储引擎不能使用索引中范围条件右边的列


EXPLAIN SELECT * FROM staffs WHERE name='July' AND age>25 AND pos='dev';


20200215153731688.png


age条件变成了范围,其之后的索引全部失效了。

**5.尽量使用覆盖索引(只访问索引的查询(查询列和索引列一致)),减少select ***

EXPLAIN SELECT name,age,pos FROM staffs WHERE name='July' AND age>25 AND pos='dev';

20200215154333494.png


可见,性能提升。


6.MySQL在使用不等于(!=或< >)的时候无法使用索引会导致全表扫描


20200215154806309.png

7.is null.is not null也无法使用索引

20200215155025173.png

8.like以通配符开头(’%abc…’),索引会失效,变成全表扫描的操作


EXPLAIN SELECT * FROM staffs WHERE name LIKE '%July%';


20200215155355475.png


EXPLAIN SELECT * FROM staffs WHERE name LIKE '%July';

20200215155433787.png

EXPLAIN SELECT * FROM staffs WHERE name LIKE 'July%';

20200215155433787.png


可见,前两条语句索引会失效。于是得出又一个口诀,like %写右边。但是,如果工作中需要用到两边都有%的语句,应该怎么样解决索引不被使用呢?


下面建立一个tbl_user表来进行演示

20200215163925359.png

现在在name和age自动上建立索引


CREATE INDEX idx_user_nameAge ON tbl_user(name,age);


分析以下的SQL语句


EXPLAIN SELECT name,age FROM tbl_user WHERE NAME like '%aa%';


结果如下:

20200215164407667.png


显然使用到了索引idx_user_nameAge ;


下面分析以下SQL语句


EXPLAIN SELECT id FROM tbl_user WHERE NAME like '%aa%';


结果如下:

20200215164558242.png


显然使用了主键索引id;

下面分析以下SQL语句:


EXPLAIN SELECT name FROM tbl_user WHERE NAME like '%aa%';


结果如下:


20200215164722886.png


显然用到了索引idx_user_nameAge

下面分析以下SQL语句:


EXPLAIN SELECT age FROM tbl_user WHERE NAME like '%aa%';


结果如下:

20200215164837936.png


显然使用了索引idx_user_nameAge

如果查询id,name或id,name,age或name,age,索引都是不失效的。


但是如果是以下的SQL语句


EXPLAIN SELECT * FROM tbl_user WHERE NAME like '%aa%';


20200215165122473.png


此时,索引失效。

再分析以下语句:


EXPLAIN SELECT id,name,age,email FROM tbl_user WHERE NAME like '%aa%';


结果如下:


20200215165301993.png

显然,索引失效。

因此,结论就是如果要使用%abc%来做模糊查询,要建立覆盖索引,查询的字段范围不能超过索引所在的字段范围。


9.字符串不加单引号,索引失效

来看看staffs表:

20200215171633124.png


以下两条SQL语句


SELECT * FROM staffs WHERE name=2000;
SELECT * FROM staffs WHERE name='2000';


查询结果相同,如下:

20200215171901388.png


但是根据3中所提到的不要在索引字段上进行任何操作的规则,SELECT * FROM staffs WHERE name=2000; 语句在name字段上进行了类型转换,将2000转成了字符串类型来进行查询,因此索引会失效。


10.少用or,用or来连接时会索引失效


20200215172626244.png


一些小练习:


20200215173152185.png

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3天前
|
SQL 关系型数据库 MySQL
大厂面试官:聊下 MySQL 慢查询优化、索引优化?
MySQL慢查询优化、索引优化,是必知必备,大厂面试高频,本文深入详解,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验分享。
大厂面试官:聊下 MySQL 慢查询优化、索引优化?
|
24天前
|
存储 关系型数据库 MySQL
阿里面试:为什么要索引?什么是MySQL索引?底层结构是什么?
尼恩是一位资深架构师,他在自己的读者交流群中分享了关于MySQL索引的重要知识点。索引是帮助MySQL高效获取数据的数据结构,主要作用包括显著提升查询速度、降低磁盘I/O次数、优化排序与分组操作以及提升复杂查询的性能。MySQL支持多种索引类型,如主键索引、唯一索引、普通索引、全文索引和空间数据索引。索引的底层数据结构主要是B+树,它能够有效支持范围查询和顺序遍历,同时保持高效的插入、删除和查找性能。尼恩还强调了索引的优缺点,并提供了多个面试题及其解答,帮助读者在面试中脱颖而出。相关资料可在公众号【技术自由圈】获取。
|
7天前
|
SQL 关系型数据库 MySQL
MySQL慢查询优化、索引优化、以及表等优化详解
本文详细介绍了MySQL优化方案,包括索引优化、SQL慢查询优化和数据库表优化,帮助提升数据库性能。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
MySQL慢查询优化、索引优化、以及表等优化详解
|
12天前
|
缓存 监控 关系型数据库
如何优化MySQL查询速度?
如何优化MySQL查询速度?【10月更文挑战第31天】
37 3
|
14天前
|
缓存 关系型数据库 MySQL
如何优化 MySQL 数据库的性能?
【10月更文挑战第28天】
38 1
|
21天前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:百万级数据统计优化实践
【10月更文挑战第21天】 在处理大规模数据集时,传统的单体数据库解决方案往往力不从心。MySQL和Redis的组合提供了一种高效的解决方案,通过将数据库操作与高速缓存相结合,可以显著提升数据处理的性能。本文将分享一次实际的优化案例,探讨如何利用MySQL和Redis共同实现百万级数据统计的优化。
54 9
|
15天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
81 1
|
21天前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:优化百万数据查询的实战经验
【10月更文挑战第13天】 在处理大规模数据集时,传统的关系型数据库如MySQL可能会遇到性能瓶颈。为了提升数据处理的效率,我们可以结合使用MySQL和Redis,利用两者的优势来优化数据查询。本文将分享一次实战经验,探讨如何通过MySQL与Redis的协同工作来优化百万级数据统计。
48 5
|
26天前
|
存储 关系型数据库 MySQL
如何在MySQL中进行索引的创建和管理?
【10月更文挑战第16天】如何在MySQL中进行索引的创建和管理?
54 1
|
26天前
|
存储 关系型数据库 MySQL
优化 MySQL 的锁机制以提高并发性能
【10月更文挑战第16天】优化 MySQL 锁机制需要综合考虑多个因素,根据具体的应用场景和需求进行针对性的调整。通过不断地优化和改进,可以提高数据库的并发性能,提升系统的整体效率。
47 1