MySQL面试常问问题(SQL 优化 ) —— 赶快收藏

news2025/8/16 3:34:18

目录

1.慢SQL如何定位呢?

2.有哪些方式优化慢SQL?

避免不必要的列

分页优化

索引优化

JOIN优化

排序优化

UNION优化

3.怎么看执行计划(explain),如何理解其中各个字段的含义?


1.慢SQL如何定位呢?

慢SQL的监控主要通过两个途径:

发现慢SQL

  • 慢查询日志:开启MySQL的慢查询日志,再通过一些工具比如mysqldumpslow去分析对应的慢查询日志,当然现在一般的云厂商都提供了可视化的平台。

  • 服务监控:可以在业务的基建中加入对慢SQL的监控,常见的方案有字节码插桩、连接池扩展、ORM框架过程,对服务运行中的慢SQL进行监控和告警。

2.有哪些方式优化慢SQL?

慢SQL的优化,主要从两个方面考虑,SQL语句本身的优化,以及数据库设计的优化。

避免不必要的列

这个是老生常谈,但还是经常会出的情况,SQL查询的时候,应该只查询需要的列,而不要包含额外的列,像slect * 这种写法应该尽量避免。

分页优化

在数据量比较大,分页比较深的情况下,需要考虑分页的优化。

例如:

select * from table where type = 2 and level = 9 order by id asc limit 190289,10;

优化方案:

  • 延迟关联

先通过where条件提取出主键,在将该表与原数据表关联,通过主键id提取数据行,而不是通过原来的二级索引提取数据行

例如:

select a.* from table a, 
 (select id from table where type = 2 and level = 9 order by id asc limit 190289,10 ) b
 where a.id = b.id
  • 书签方式

书签方式就是找到limit第一个参数对应的主键值,根据这个主键值再去过滤并limit

例如:

select * from table where id >
  (select * from table where type = 2 and level = 9 order by id asc limit 190

索引优化

合理地设计和使用索引,是优化慢SQL的利器。

利用覆盖索引

InnoDB使用非主键索引查询数据时会回表,但是如果索引的叶节点中已经包含要查询的字段,那它没有必要再回表查询了,这就叫覆盖索引

例如对于如下查询:

select name from test where city='上海'

我们将被查询的字段建立到联合索引中,这样查询结果就可以直接从索引中获取

lter table test add index idx_city_name (city, name);

低版本避免使用or查询

在 MySQL 5.0 之前的版本要尽量避免使用 or 查询,可以使用 union 或者子查询来替代,因为早期的 MySQL 版本使用 or 查询可能会导致索引失效,高版本引入了索引合并,解决了这个问题。

避免使用 != 或者 <> 操作符

SQL中,不等于操作符会导致查询引擎放弃查询索引,引起全表扫描,即使比较的字段上有索引

解决方法:通过把不等于操作符改成or,可以使用索引,避免全表扫描

例如,把column<>’aaa’,改成column>’aaa’ or column<’aaa’,就可以使用索引了

适当使用前缀索引

适当地使用前缀所云,可以降低索引的空间占用,提高索引的查询效率。

比如,邮箱的后缀都是固定的“@xxx.com”,那么类似这种后面几位为固定值的字段就非常适合定义为前缀索引

alter table test add index index2(email(6));

PS:需要注意的是,前缀索引也存在缺点,MySQL无法利用前缀索引做order by和group by 操作,也无法作为覆盖索引

避免列上函数运算

要避免在列字段上进行算术运算或其他表达式运算,否则可能会导致存储引擎无法正确使用索引,从而影响了查询的效率

select * from test where id + 1 = 50;
select * from test where month(updateTime) = 7;

正确使用联合索引

使用联合索引的时候,注意最左匹配原则。

JOIN优化

优化子查询

尽量使用 Join 语句来替代子查询,因为子查询是嵌套查询,而嵌套查询会新创建一张临时表,而临时表的创建与销毁会占用一定的系统资源以及花费一定的时间,同时对于返回结果集比较大的子查询,其对查询性能的影响更大

小表驱动大表

关联查询的时候要拿小表去驱动大表,因为关联的时候,MySQL内部会遍历驱动表,再去连接被驱动表。

比如left join,左表就是驱动表,A表小于B表,建立连接的次数就少,查询速度就被加快了。

select name from A left join B ;

适当增加冗余字段

增加冗余字段可以减少大量的连表查询,因为多张表的连表查询性能很低,所有可以适当的增加冗余字段,以减少多张表的关联查询,这是以空间换时间的优化策略

避免使用JOIN关联太多的表

《阿里巴巴Java开发手册》规定不要join超过三张表,第一join太多降低查询的速度,第二join的buffer会占用更多的内存。

如果不可避免要join多张表,可以考虑使用数据异构的方式异构到ES中查询。

排序优化

利用索引扫描做排序

MySQL有两种方式生成有序结果:其一是对结果集进行排序的操作,其二是按照索引顺序扫描得出的结果自然是有序的

但是如果索引不能覆盖查询所需列,就不得不每扫描一条记录回表查询一次,这个读操作是随机IO,通常会比顺序全表扫描还慢

因此,在设计索引时,尽可能使用同一个索引既满足排序又用于查找行

例如:

--建立索引(date,staff_id,customer_id)
select staff_id, customer_id from test where date = '2010-01-01' order by staff_id,customer_id;

只有当索引的列顺序和ORDER BY子句的顺序完全一致,并且所有列的排序方向都一样时,才能够使用索引来对结果做排序

UNION优化

条件下推

MySQL处理union的策略是先创建临时表,然后将各个查询结果填充到临时表中最后再来做查询,很多优化策略在union查询中都会失效,因为它无法利用索引

最好手工将where、limit等子句下推到union的各个子查询中,以便优化器可以充分利用这些条件进行优化

此外,除非确实需要服务器去重,一定要使用union all,如果不加all关键字,MySQL会给临时表加上distinct选项,这会导致对整个临时表做唯一性检查,代价很高。

3.怎么看执行计划(explain),如何理解其中各个字段的含义?

explain是sql优化的利器,除了优化慢sql,平时的sql编写,也应该先explain,查看一下执行计划,看看是否还有优化的空间。

直接在 select 语句之前增加explain 关键字,就会返回执行计划的信息。

explain

explain

  1. id 列:MySQL会为每个select语句分配一个唯一的id值

  2. select_type 列,查询的类型,根据关联、union、子查询等等分类,常见的查询类型有SIMPLE、PRIMARY。

  3. table 列:表示 explain 的一行正在访问哪个表。

  4. type 列:最重要的列之一。表示关联类型或访问类型,即 MySQL 决定如何查找表中的行。

    性能从最优到最差分别为:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

    • system

      system:当表仅有一行记录时(系统表),数据量很少,往往不需要进行磁盘IO,速度非常快

    • const

      const:表示查询时命中 primary key 主键或者 unique 唯一索引,或者被连接的部分是一个常量(const)值。这类扫描效率极高,返回数据量少,速度非常快。

    • eq_ref

      eq_ref:查询时命中主键primary key 或者 unique key索引, type 就是 eq_ref

    • ref_or_null

      ref_or_null:这种连接类型类似于 ref,区别在于 MySQL会额外搜索包含NULL值的行。

    • index_merge

      index_merge:使用了索引合并优化方法,查询使用了两个以上的索引。

    • unique_subquery

      unique_subquery:替换下面的 IN子查询,子查询返回不重复的集合。

    • index_subquery

      index_subquery:区别于unique_subquery,用于非唯一索引,可以返回重复值。

    • range

      range:使用索引选择行,仅检索给定范围内的行。简单点说就是针对一个有索引的字段,给定范围检索数据。在where语句中使用 bettween...and<><=in 等条件查询 type 都是 range

    • index

      indexIndex 与ALL 其实都是读全表,区别在于index是遍历索引树读取,而ALL是从硬盘中读取。

    • ALL

      就不用多说了,全表扫描。

  5. possible_keys 列:显示查询可能使用哪些索引来查找,使用索引优化sql的时候比较重要。

  6. key 列:这一列显示 mysql 实际采用哪个索引来优化对该表的访问,判断索引是否失效的时候常用。

  7. key_len 列:显示了 MySQL使用

  8. ref 列:ref 列展示的就是与索引列作等值匹配的值,常见的有:const(常量),func,NULL,字段名。

  9. rows 列:这也是一个重要的字段,MySQL查询优化器根据统计信息,估算SQL要查到结果集需要扫描读取的数据行数,这个值非常直观显示SQL的效率好坏,原则上rows越少越好。

  10. Extra 列:显示不适合在其它列的额外信息,虽然叫额外,但是也有一些重要的信息:

  • Using index:表示MySQL将使用覆盖索引,以避免回表

  • Using where:表示会在存储引擎检索之后再进行过滤

  • Using temporary :表示对查询结果排序时会使用一个临时表。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/110418.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于python开发的DIY宠物桌面系统(附源码)--可自定义修改

定制你的宠物桌面 最近想要做一个自己独一无二的桌面宠物&#xff0c;可以直接使用python来自己订制。属于一个小项目&#xff0c;这个教程主要包含几个步骤&#xff1a; 准备需要的动图素材 规划自己需要的功能 使用python的PyQt5订制功能 在这个教程中&#xff0c;我主要…

Apache Flink 任务 Tasks 和任务槽 Task Slots

目录 任务槽&#xff08;Task Slots&#xff09; 任务槽数量的设置 任务对任务槽的共享 任务槽和并行度的关系 任务槽&#xff08;Task Slots&#xff09; Flink 中每一个 worker(也就是 TaskManager)都是一个 JVM 进程&#xff0c;它可以启动多个独立的线程&#xff0c;来并…

【数据结构】详解队列和循环队列

目录一.队列1.队列的概念及结构2.队列的实现Queue.hQueue.c二.循环队列1.循环队列的实现2.设计循环队列解题思路代码一.队列 1.队列的概念及结构 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出…

四、网络层(六)移动IP

目录 6.1 移动IP的概念 6.2 移动IP的基本工作原理 6.2.1代理发现与注册 6.2.2固定主机向移动主机发送IP数据报 6.2.3移动主机向固定主机发送IP数据报 6.2.4同址转交地址&#xff08;简单了解&#xff09; 6.2.5三角形路由问题&#xff08;简单了解&#xff09; 6.1 移…

事关你“吃住行游购娱”的12项安全国标图解来了

标准是安全建设的“尺子”。近期&#xff0c;国家市场监督管理总局、国家标准化管理委员会发布中华人民共和国国家标准公告&#xff08;2022年第13号&#xff09;&#xff0c;全国信息安全标准化技术委员会归口的14项网络安全国家标准获批发布&#xff0c;其中12项涉及数据安全…

不同类型单板布线策略6大类

类型一PCB布线策略 一 &#xff0c;类型一主要特征如下&#xff1a; 严格的长度规则、严格的串扰规则、拓扑规则、差分规则、电源地规则等。 二&#xff0c;关键网络的处理&#xff1a;总线定义Class&#xff1b; 要求满足一定的拓扑结构、stub及其长度&#xff08;时域&a…

关于模型中的R方

1、一元线性回归 R方在一元线性回归模型中&#xff0c;衡量【响应变量X和预测变量Y】的线性关系。 R方cor&#xff08;X,Y)^2 但是&#xff0c;在多元线性回归模型中&#xff0c;因为涉及多个预测变量&#xff0c;全部R方就是衡量响应变量和多个预测变量当中的关系。 而有关…

阿里云张献涛:高性能计算发展的三大趋势

12 月 12-15 日&#xff0c;第十八届 CCF 全国高性能计算学术年会&#xff08;以下简称 CCF HPC China 2022&#xff09;以线上的方式举行&#xff0c;国内外众多知名专家学者&#xff0c;以及高性能计算产业界的头部企业代表云上相聚&#xff0c;探讨高性能计算的发展趋势。阿…

zabbix6.0安装教程(五):二进制包安装

zabbix6.0安装教程&#xff08;五&#xff09;&#xff1a;二进制包安装 目录一、使用ZABBIX官方存储库二、Red Hat zabbix企业版 Linux/CentOS1. 概述2. 安装注意事项2.1 使用 Timescale DB 导入数据2.2 PHP 7.22.3 配置 SELinux3. Proxy 安装3.1 创建数据库3.2 导入数据3.3 为…

计算机网络原理第5章 运输层(12.24完结)

目录~ 5.1 运输层协议概述 5.1.1 进程之间的通信 从通信和信息处理的角度看&#xff0c;运输层向它上面的应用层提供通信服务&#xff0c;它属于面向通信部分的最高层&#xff0c;同时也是用户功能中的最低层。 当网络的边缘部分中的两个主机使用网络的核心部分的功能进行…

再学C语言12:字符串(3)——转换说明

一、转换说明的意义 意义&#xff1a;把存储在计算机中的二进制格式的数值转换成一系列字符&#xff08;一个字符串&#xff09;以便于显示&#xff1b;实质上是翻译说明&#xff0c;并不会替代原值 应该使转换说明与要打印的值的类型相匹配 参数传递机制 float n1; double …

陈都灵现身海南国际电影节,新片《关索岭》票房有望超《阿凡达》

刚送走了厦门金鸡奖&#xff0c;又迎来了海南电影节&#xff0c;第四届国际电影节&#xff0c;已经在美丽的海南岛拉开帷幕。 众多的中国优秀电影人&#xff0c;都欢聚一堂共话未来&#xff0c;为中国电影的发展献言献策&#xff0c;也展现出电影人的精神风貌。 在本届电影节走…

WMS系统这么重要?一文教你找到理想中的WMS系统

无论是在线上还是线下&#xff0c;相信大家都见过各式各样的仓库&#xff0c;或杂乱或整洁&#xff0c;有的还在使用传统的纸单作业模式&#xff0c;有的已经进入全自动化无人作业模式。然而&#xff0c;随着仓储物流行业竞争愈发激烈&#xff0c;以及数智化转型浪潮席卷而来&a…

python中logging模块的一些简单用法

用Python写代码的时候&#xff0c;在想看的地方写个print xx 就能在控制台上显示打印信息&#xff0c;这样子就能知道它是什么了&#xff0c;但是当我需要看大量的地方或者在一个文件中查看的时候&#xff0c;这时候print就不大方便了&#xff0c;所以Python引入了logging模块来…

小学生C++编程基础 课程8(B)

919.3数排序 ( 课程8) 登录 920.求最小值 (课程8) 登录 921.排名 (课程8) 登录 922.中间数 ( 课程8&#xff09; 难度&#xff1a;1 登录 923.判断闰年 &#xff08;课程8&#xff09; 难度&#xff1a;1 登录 924.天数 (课程8) 难度&#xff1a;1 登录 《小学生C趣味编程…

Splunk Enterprise 存在任意代码执行漏洞

漏洞描述 Splunk 是一款机器数据的引擎&#xff0c;可用于收集、索引和利用所有应用程序、服务器和设备生成的快速移动型计算机数据 。 Splunk 受影响版本存在任意代码执行漏洞&#xff0c;经过身份验证的攻击者可利用此漏洞通过创建包含恶意代码的 SimpleXML 仪表板&#xf…

说话人识别中的损失函数

损失函数 损失函数L(yi,y^i)L(y_i,\hat{y}_i)L(yi​,y^​i​)用来描述神经网络的输出y^i\hat{y}_iy^​i​和基本事实&#xff08;Ground Truth&#xff0c;GT&#xff09;yiy_iyi​的差异对于回归问题&#xff0c;常用均方误差&#xff08;Mean Square Error&#xff0c;MSE&a…

IB成绩该如何换算GPA?

今天就简单介绍下IB课程分数与GPA以及英国的UCAS Tariff points的分数换算&#xff01; 网传的换算方法是这样的&#xff1a; 以IB单科满分是7分为前提&#xff0c;那么把IB成绩换算成四分制的GPA的方式是&#xff1a;将IB课程分数除以7再乘以4。 举个例子&#xff0c;你某门科…

【有营养的算法笔记】从推导证明的角度深剖前缀和与差分算法

&#x1f451;作者主页&#xff1a;进击的安度因 &#x1f3e0;学习社区&#xff1a;进击的安度因&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;有营养的算法笔记 文章目录一、一维前缀和1、算法推导2、代码实现二、二维前缀和1、算法推导2、代码实现三…

数据库范式

1 数据库范式 完全函数依赖 &#xff08;Sno,Cno) —> Grade 是完全函数依赖&#xff0c;学号不能得出成绩&#xff0c;学科号也不能推出成绩。 部分函数依赖 &#xff08;Sno,Cno) --> Sdept 是部分函数依赖&#xff0c;学号能推出院系。 传递依赖 Sno --> Sdep…