带你学MySQL系列 | “数据分析师”面试最怕被问到的SQL优化问题(下)(四)

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 带你学MySQL系列 | “数据分析师”面试最怕被问到的SQL优化问题(下)(四)

8)extra

表示其他的一些说明,也非常有用,通过这个关键字也可以很好的说明,你写的SQL语句到底好不好。


① using filesort:针对单索引的情况

当出现了这个词,表示你当前的SQL性能消耗较大。表示进行了一次额外的排序。常见于order by语句中。

Ⅰ 什么是“额外”的排序?

为了讲清楚这个,我们首先要知道什么是排序。我们为了给某一个字段进行排序的时候,首先你得先查询到这个字段,然后在将这个字段进行排序。

紧接着,我们查看如下两个SQL语句的执行计划。


# 新建一张表,建表同时创建索引
create table test02
(
  a1 char(3),
  a2 char(3),
  a3 char(3),
  index idx_a1(a1),
  index idx_a2(a2),
  index idx_a3(a3)
);
# 查看执行计划
explain select * from test02 where a1 ='' order by a1 ;
explain select * from test02 where a1 ='' order by a2 ;


结果如下:

image.png

结果分析:对于第一个执行计划,where后面我们先查询了a1字段,然后再利用a1做了依次排序,这个很轻松。但是对于第二个执行计划,where后面我们查询了a1字段,然而利用的却是a2字段进行排序,此时myql底层会进行一次查询,进行“额外”的排序。

总结:对于单索引,如果排序和查找是同一个字段,则不会出现using filesort;如果排序和查找不是同一个字段,则会出现using filesort;因此where哪些字段,就order by哪些些字段。


② using filesort:针对复合索引的情况(贼重要)

不能跨列(官方术语:最佳左前缀),这句话一定要牢记!!!

# 删除test02的索引
drop index idx_a1 on test02;
drop index idx_a2 on test02;
drop index idx_a3 on test02;
# 创建一个复合索引
alter table test02 add index idx_a1_a2_a3 (a1,a2,a3) ;
# 查看下面SQL语句的执行计划
explain select *from test02 where a1='' order by a3 ;  --using filesort
explain select *from test02 where a2='' order by a3 ; --using filesort
explain select *from test02 where a1='' order by a2 ;


结果如下:

image.png

结果分析:复合索引的顺序是(a1,a2,a3),可以看到a1在最左边,因此a1就叫做最佳左前缀,如果要使用后面的索引字段,必须先使用到这个a1字段。对于explain1,where后面我们使用a1字段,但是后面的排序使用了a3,直接跳过了a2,属于跨列;对于explain2,where后面我们使用了a2字段,直接跳过了a1字段,也属于跨列;对于explain3,where后面我们使用a1字段,后面使用的是a2字段,因此没有出现【using filesort】。


③ using temporary

当出现了这个词,也表示你当前的SQL性能消耗较大。这是由于当前SQL用到了临时表,一般出现在group by中。

explain select a1 from test02 where a1 in ('1','2','3') group by a1 ;
explain select a1 from test02 where a1 in ('1','2','3') group by a2 ; --using temporary


结果如下:

image.png

结果分析:当你查询哪个字段,就按照那个字段分组,否则就会出现using temporary。


---------------------------------------------------------------------------------------------------------------


针对using temporary,我们在看一个例子:


using temporary表示需要额外再使用一张表,一般出现在group by语句中。虽然已经有表了,但是不适用,必须再来一张表。


再次来看mysql的编写过程和解析过程。


Ⅰ 编写过程


select dinstinct  ..from  ..join ..on ..where ..group by ..having ..order by ..limit ..


Ⅱ 解析过程


from .. on.. join ..where ..group by ..having ..select dinstinct ..order by ..limit ..


很显然,where后是group by,然后才是select。基于此,我们再查看如下两个SQL语句的执行计划。


explain select * from test03 where a2=2 and a4=4 group by a2,a4;
explain select * from test03 where a2=2 and a4=4 group by a3;


分析如下:对于第一个执行计划,where后面是a2和a4,接着我们按照a2和a4分组,很明显这两张表已经有了,直接在a2和a4上分组就行了。但是对于第二个执行计划,where后面是a2和a4,接着我们却按照a3分组,很明显我们没有a3这张表,因此有需要再来一张临时表a3,因此就会出现using temporary。


④ using index

当你看到这个关键词,恭喜你,表示你的SQL性能提升了。

using index称之为 索引覆盖。

当出现了using index,就表示不用读取源表,而只利用索引获取数据,不需要回源表查询。

只要使用到的列,全部出现在索引中,就是索引覆盖。

# 删除test02中的复合索引idx_a1_a2_a3
drop index idx_a1_a2_a3 on test02;
# 重新创建一个复合索引idx_a1_a2
create index idx_a1_a2 on test02(a1,a2);
# 查看执行计划
explain select a1,a3 from test02 where a1='' or a3= '' ;
explain select a1,a2 from test02 where a1='' and a2= '' ;


结果如下:

image.png

结果分析:这里我们创建的是a1和a2的复合索引,对于第一个执行计划,我们却出现了a3,该字段并没有创建索引,因此没有出现using index,而是using where,表示我们需要回表查询。对于第二个执行计划,属于完全的索引覆盖,因此出现了using index。

----------------------------------------------------------------------------------------------------------------

针对using index,我们在查看一个案例:


explain select a1,a2 from test02 where a1='' or a2= '' ;
explain select a1,a2 from test02  ;


结果如下:

image.png

如果用到了索引覆盖(using index时),会对possible_keys和key造成影响:


a.如果没有where,则索引只出现在key中;

b.如果有where,则索引 出现在key和possible_keys中。


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1天前
|
SQL 关系型数据库 MySQL
:“You have an error in your SQL syntax; check the manual that corresponds to your MySQL server versi
:“You have an error in your SQL syntax; check the manual that corresponds to your MySQL server versi
6 0
|
5天前
|
SQL 关系型数据库 MySQL
Python与MySQL数据库交互:面试实战
【4月更文挑战第16天】本文介绍了Python与MySQL交互的面试重点,包括使用`mysql-connector-python`或`pymysql`连接数据库、执行SQL查询、异常处理、防止SQL注入、事务管理和ORM框架。易错点包括忘记关闭连接、忽视异常处理、硬编码SQL、忽略事务及过度依赖低效查询。通过理解这些问题和提供策略,可提升面试表现。
25 6
|
5天前
|
存储 Oracle 关系型数据库
【MySQL面试题pro版-12】
【MySQL面试题pro版-12】
13 0
|
5天前
|
SQL 关系型数据库 MySQL
【MySQL面试题pro版-10】
【MySQL面试题pro版-10】
13 1
|
5天前
|
缓存 关系型数据库 MySQL
【MySQL面试题pro版-9】
【MySQL面试题pro版-9】
19 1
|
5天前
|
存储 SQL 关系型数据库
【MySQL面试题pro版-8】
【MySQL面试题pro版-8】
11 0
|
5天前
|
存储 SQL 关系型数据库
【MySQL面试题pro版-7】
【MySQL面试题pro版-7】
17 0
|
5天前
|
存储 关系型数据库 MySQL
【MySQL面试题pro版-6】
【MySQL面试题pro版-6】
18 0
|
26天前
|
Java 程序员
java线程池讲解面试
java线程池讲解面试
49 1
|
2月前
|
存储 关系型数据库 MySQL
2024年Java秋招面试必看的 | MySQL调优面试题
随着系统用户量的不断增加,MySQL 索引的重要性不言而喻,对于后端工程师,只有在了解索引及其优化的规则,并应用于实际工作中后,才能不断的提升系统性能,开发出高性能、高并发和高可用的系统。 今天小编首先会跟大家分享一下MySQL 索引中的各种概念,然后介绍优化索引的若干条规则,最后利用这些规则,针对面试中常考的知识点,做详细的实例分析。
246 0
2024年Java秋招面试必看的 | MySQL调优面试题

热门文章

最新文章