所以,多列索引的顺序是需要考虑的 。这里给出的建议是,将选择性最高的索引列放在前面 。
接上面的例子,还是 LastName 和 FirstName 作为多列索引 。看谁应该放前面 。
通过按照选择性规则,写如下 SQL 语句:
先计算LastName的选择性 Selectcount(disctinc LastName)/count(*) from user 结果为0.02 再计算FirstName的选择性 Selectcount(disctinc FirstName)/count(*) from user 结果0.05 FirstName 的选择性要高于 LastName 的选择性 。因此调整多列索引的顺序如下:
Alter tableuser add key(FirstName ,LastName) 覆盖索引
当使用 Select 的数据列只用从索引中取得,而不必从数据表中读取,换句话说查询列要被所使用的索引覆盖 。
例如:User 表中将 LastName 作为索引 。如果写以下查询语句:
Select LastName from user LastName 及作为索引,又在查询内容中显示出来,那么 LastName 就是覆盖索引 。
覆盖索引是高效查找行方法,通过索引就可以读取数据,就不需要再到数据表中读取数据了 。
而且覆盖索引会以 Usingindex 作为标示,可以通过 Explain 语句查看 。
文章插图
Explain 查看覆盖索引标示
覆盖索引主要应用在 Count 等一些聚合操作上,提升查询的效率 。例如上面提到的 Selectcount(LastName) from user 就可以把 LastName 设置为索引 。
还有可以进行列查询的回表优化,如下:
Select LastName, FirstName from user where LastName=‘Jack’ 如果此时 LastName 设置为索引,可以将 LastName 和 FirstName 设置为多列索引(联合索引) 。
避免回表行为的发生 。这里的回表是指二级索引搜索到以后,再找到聚合索引,然后在查找 PK 的过程 。
这里需要通过两次搜索完成 。简单点说就是使用了覆盖索引以后,一次就可以查到想要的记录,不用在查第二次了 。
文章插图
回表示意图
查询优化
作为程序开发人员来说,使用得最多的就是 SQL 语句了,最多的操作就是查询了 。
我们一起来看看,哪些因素会影响查询记录,查询基本原理是什么,以及如何发现和优化 SQL 语句 。
影响查询效率的因素
一般来说,影响查询的因素有三部分组成,如下:
- 响应时间,由两部分组成,他们分别是,服务时间和排队时间 。服务时间是指数据库处理查询花费的时间 。
- 扫描记录行数,在查询过程中数据库锁扫描的行记录 。理想情况下扫描的行数和返回的行数是相同的 。不过通常来说,扫描的行数都会大于返回记录的行数 。
- 返回记录行数,返回实际要查询的结果 。
文章插图
查询流程图
说了影响查询效率的因素以后,来看看查询这件事情在 MySQL 中是如何运作的,可以帮助我理解,查询优化工作是在哪里进行的:
- 客户端发送一条查询给服务器 。
- 服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果 。
- 解析器对 SQL 进行解析,它通过关键字将 SQL 语句进行解析,并生成一棵对应的“解析树” 。MySQL 解析器将使用 MySQL 语法规则验证和解析查询 。
- 预处理器则根据一些 MySQL 规则进一步检查解析树是否合法,并且验证权限 。例如,检查数据表和数据列是否存在,解析名字和别名看是否有歧义 。
- MySQL 根据优化器生成的执行计划,调用存储引擎的 API 来执行查询 。
- 将结果返回给客户端 。
说了影响查询缓慢的因素以及查询的基本流程以后,再来看看如何发现查询慢的 SQL 。这里 MySQL 提供了日志,其中可以查询执行比较慢的 SQL 。
①查看慢查询日志是否开启
SHOWVARIABLESLIKE'%slow_query_log%';
文章插图
②如果没有开启,通过命令开启慢查询日志
SETGLOBAL slow_query_log=1;
文章插图
推荐阅读
- 我们悄悄优化了页面载入速度
- 10款最佳的MySQL GUI工具,数据库管理员的好帮手
- mysql 分区表使用介绍
- MySQL主从复制没使用过?三大步骤让你从原理、业务上理解透彻
- 福特安全性能怎么样 福特车好吗?耐用性,安全系数高吗?
- 优化你的SpringBoot
- Mysql报too many connections详解
- Mysql访问中间件--Atlas初探
- 找出Android卡顿的元凶——渲染性能优化
- 我常用的免费MySQL图形化管理工具