MySQL索引优化(一)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MySQL索引优化(一)

MySQL索引优化(案例)


索引单表优化


案例:


(1)首先建立一个article表:


202002131109443.png


往其中插入三条数据:


20200213111035955.png

(2)查询category_id为1且comments大于1的情况下,views最多的article_id


 select id,author_id from article where category_id=1 and comments>1 order by views desc limit 1;

查询结果如下:

20200213111257340.png

使用explain语句来分析这条sql语句写得好不好

explain select id,author_id from article where category_id=1 and comments>1 order by views desc limit 1;

结果如下:


20200213111543656.png


type为ALL:说明是全表扫描,不好

Extra显示Using filesort:说明MySQL中无法用索引来排序,所以MySQL会用外部排序——即文件内排序来排序数据并返回查询结果,这样子也不好


(3)我们来查询一下article表的索引(其实是没有的,因为建表时只是将id设为了主键,没有建立除主键索引以外的索引)

SHOW INDEX FROM article;

20200213112206957.png


由图可见,索引是主键索引,下面开始优化


优化:


(1)新建索引,发现该索引不合适,删除该索引


由于上述查询语句中用到了category_id,comments,views字段作为查询条件,所以尝试将索引应该建在这三个条件上面

CREATE INDEX idx_article_ccv ON article(category_id,comments,views);

建好索引后再查询一下全部索引:


20200213112957195.png


现在再来分析一下查询语句的性能


explain select id,author_id from article where category_id=1 and comments>1 order by views


20200213113149251.png


发现type字段下的ALL变成了range,用到了idx_article_ccv索引,但是Using filesort还有。


如果sql语句中comments>1条件改为了comments=3,那么性能分析会呈现以下情况:


20200213113845369.png



可以看到,Using filesort没有了,type字段下的range变成了ref。


这就是范围查询带来的索引失效问题,因为按照BTree索引的工作原理,先排序category_id,若遇到相同category_id再排序comments,若遇到相同的comments再排序views,当comments字段在联合索引里处于中间位置时,comments>1条件是一个范围值(range),MySQL无法利用索引再对后面的views部分进行检索,即range类型查询字段后面的索引失效。这个问题会在本文后面得到解决。


现在删除idx_article_ccv索引,重新建立新的索引


(2)重建索引


绕过comments字段,在categroy_id和views字段上建索引:


CREATE INDEX idx_article_cv ON article(category_id,views);


再次使用explain来分析该查询语句的性能


explain select id,author_id from article where category_id=1 and comments>1 order by vi


20200213115331486.png


由图可见,使用了这个索引已经将该sql语句优化到最佳效果!


索引两表优化


案例


(1)建立一个class表和一个book表

class表(id为主键自增):

20200214105228122.png


book表(bookid为主键自增):


20200214105527556.png


(2)使用explain语句进行性能分析


EXPLAIN SELECT * FROM class LEFT JOIN book ON class.card=book.card;


20200214110239776.png


此时,type为ALL,显然需要优化

(3)对右表book表添加索引


CREATE INDEX idx_book_card ON book(card);


再用explain语句分析(2)中的查询语句,结果如下:


20200214110828351.png


由此可见,性能有明显的提升

现在删去索引idx_book_card

(4)对左表class表添加索引


CREATE INDEX idx_class_card ON class(card);


再用explain语句分析(2)中的查询语句,结果如下:


20200214111147738.png


与(3)中的结果对比可见,将索引建立在右表上性能好。


(5)结论


通过分析可得出结论,如果SQL语句是LEFT JOIN,则在右表建立索引;如果SQL语句是RIGHT JOIN,则在左表建立索引


索引三表优化


(1)再建立一个phone表(phoneid为主键自增),并把这三个表中的索引全部删去


20200214112440441.png

(2)来用explain语句分析以下语句


EXPLAIN SELECT * FROM class LEFT JOIN book ON class.card=book.card LEFT JOIN phone ON book.c


结果为:


20200214122326879.png


(3)在book表和phone表上的card字段建索引


CREATE INDEX idx_book_card ON book(card);
CREATE INDEX idx_phone_card ON phone(card);


继续用explain语句分析(2)中的SQL语句:

20200214122756262.png



从type属性和rows属性以及Extra属性中看到,建立索引后效率提升了很多


(4)结论:


尽可能减少join语句中的Nested Loop的循环总次数,“永远用小结果集驱动大的结果集;


优化要先优化Nested Loop的内层循环;

保证Join语句中被驱动表上Join条件字段已经被索引;

当无法保证被驱动表的Join条件字段被索引且内存资源充足的前提下,不要太吝啬JoinBuffer的设置

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
6天前
|
SQL 缓存 关系型数据库
下次老板问你MySQL如何优化时,你可以这样说,老板默默给你加工资
【5月更文挑战第20天】下次老板问你MySQL如何优化时,你可以这样说,老板默默给你加工资
28 3
|
15天前
|
SQL 存储 关系型数据库
Mysql优化提高笔记整理,来自于一位鹅厂大佬的笔记,阿里P7亲自教你
Mysql优化提高笔记整理,来自于一位鹅厂大佬的笔记,阿里P7亲自教你
|
17天前
|
SQL 存储 关系型数据库
【MySQL】SQL 优化
【MySQL】SQL 优化
41 0
|
1天前
|
SQL 关系型数据库 MySQL
mysql 故障排除与优化
mysql 故障排除与优化
|
1天前
|
存储 关系型数据库 MySQL
mysql 索引基本介绍
mysql 索引基本介绍
|
2天前
|
SQL 关系型数据库 MySQL
MySQL in 太慢的 3 种优化方案
MySQL中的`eq_range_index_dive_limit`参数默认值为200,影响了IN查询的执行方式。当IN列表项少于这个值时,MySQL会使用扫描索引树(精确成本计算),而多于此值则使用索引统计(快速但可能不准)来分析查询成本。大量IN值可能导致性能下降。解决方案包括:1) 分批查询;2) 使用UNION ALL创建内存临时表;3) 创建实体表存储IN值并进行JOIN操作。注意,实体表需及时清理并避免反复插入删除导致性能下降。
|
4天前
|
算法 关系型数据库 MySQL
MySQL (索引 & 事务)
MySQL (索引 & 事务)
20 3
|
5天前
|
存储 关系型数据库 MySQL
MySQL索引
MySQL索引
11 0
|
5天前
|
SQL 算法 关系型数据库
【MySQL】索引介绍、索引的数据结构
【MySQL】索引介绍、索引的数据结构
20 0
|
8天前
|
存储 数据采集 关系型数据库
✅MySQL是如何保证唯一性索引的唯一性的?
MySQL使用B树实现唯一性索引,确保高效检索和插入。事务机制和锁定协议维护InnoDB存储引擎的唯一性。唯一索引可允许NULL值,且InnoDB允许多个NULL。唯一索引查询速度快,能提升数据质量,但插入和更新时需检查唯一性,可能影响性能。