【MySQL】优化MySQL慢查询教程和Explain解析

本文介绍了如何定位和优化MySQL的慢查询SQL,包括分析慢查询日志、使用Explain解析关键字段,以及提供了一系列常见的优化手段,如合理使用索引、避免表达式操作等。
摘要由CSDN通过智能技术生成

在这里插入图片描述


MySQL 如何定位并优化慢查询Sql

根据慢日志定位查询慢sql
使用explain等工具分析sql
修改sql或者尽量让sql走索引

根据慢日志定位查询慢sql

show variables like xxx 详解mysql运行时参数
show variables like '%QUERY%'; 慢查询
show STATUS LIKE '%slow_queries%';慢查询数量
set GLOBAL slow_query_log = on; 开启慢查询
set GLOBAL long_query_time = 1; 设置慢查询上限时间

1.开启运行时参数 show variables like xxx

show variables like '%QUERY%'; 慢查询参数
show STATUS LIKE '%slow_queries%';慢查询数量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EMvY9xtR-1608014907470)(1D9F27FEBDDA4C209A069D4582E26E94)]


2.设置慢查询日志和时间

set GLOBAL slow_query_log = on; 开启慢查询
set GLOBAL long_query_time = 1; 设置慢查询上限时间(需要删除连接重连)

3.制造慢SQL或者直接打开路径查看日志

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L2nB0wO4-1608014907472)(506FC96D0F814724900EE062875814F0)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZseQsGYw-1608014907475)(1CF0FCCCB77749DE80C4AA4574BD6609)]


4.利用explain分析执行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mt2uUifb-1608014907476)(9796CE1EC67A44BB9565C264A74927B2)]


5.具体场景分析对比日志记录

# 修改SQL
# 使用索引

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0H1bB7um-1608014907477)(8D158D3AB30449E2AA43E81D58A82A84)]


Explain 关键字段解析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O1Qrw0mX-1608014907478)(04D71D14F29D48698561965DED39638B)]

ID字段

id是一组数字,代表多个表之间的查询顺序,或者包含子句查询语句中的顺序,id 总共分为三种情况

1.id 相同,执行顺序由上至下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0N7mZAND-1608014907479)(27224D3F67824B3ABA6D4BFFA9EC875E)]

2.id 不同,如果是子查询,id 号会递增
id 值越大优先级越高,越先被执行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DCgm8EMj-1608014907480)(48B735B4A08B466FB91C27ED5D2DF1D8)]

3.id 相同和不同的情况同时存在

id相同的为一组,组内从上到到下执行,在所有组中,id越大,越优先执行


SELECT_TYPE 查询的类型

# simple 简单子查询

# primary 最外层子查询

# subquery 第一层子查询
在 select 或者 where 里包含了子查询

# derived 派生表
在 from 中包含的子查询
会被标记为衍生查询,会把查询结果放到一个临时表中

# union 出现在union后面的查询
# union result  union联合查询获取结果的select
如果有两个 select 查询语句,他们之间用 union 连起来查询
那么第二个 select 会被标记为 union,union 的结果被标记为 union result


TABLE字段

表示这一行的数据是哪张表的数据


TYPE字段(优化重要信息)

一般来说保证查询至少达到range级别,最好达到ref

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hmVuux6N-1608014907481)(6A63DEF0A69944D7B50B098805133200)]

性能从好-->差

# system
表中只有一行记录,system 是 const 的特例,几乎不会出现这种情况,可以忽略不计

# const
将主键索引或者唯一索引放到 where 条件中查询,MySQL 可以将查询条件转变成一个常量,只匹配一行数据,索引一次就找到数据了

# eq_ref
同ref差不多,但返回结果只有一体记录

# ref
不是主键索引,也不是唯一索引
就是普通的索引,可能会返回多个符合条件的行

# range
只用一个索引来选择行,key列显示所用的索引
一般是在where子句里面出现between,and,>,<等查询符合

# index
也是读取全表,但是是从索引中读取

# All
全表查询(从磁盘中读取)
 

EXTRA字段(优化重要信息)

优化时候必看的重要信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dBD0wujr-1608014907482)(40FD65704C314CF0BC60E7B0242B108D)]

# Using index:
用了覆盖索引

# Using index condition:
用了条件索引(索引下推)

# Using where:
从索引查出来数据后继续用where条件过滤

# Using join buffer (Block Nested Loop):
join的时候利用了join buffer(优化策略:去除外连接、增大join buffer大小)

# Using filesort
:用了文件排序,排序的时候没有用到索引

# Using temporary:
用了临时表(优化策略:增加条件以减少结果集、增加索引,思路就是要么减少待排序的数量,要么就提前排好序)

# Start temporary, End temporary:
子查询的时候,可以优化成半连接,但是使用的是通过临时表来去重

# FirstMatch(tbl_name):
子查询的时候,可以优化成半连接,但是使用的是直接进行数据比较来去重

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vZG3TwwV-1608014907483)(2BB9CC302F8C49B7AC6A53BB06CA9C46)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VR2NLOD3-1608014907483)(C07948F62C604FF3AA3B50F8F8C0975D)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yxgzydl2-1608014907484)(175A62B8BC0048FBAECAF5A054121982)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WqpBAUwt-1608014907485)(7B2899FC92244FC88B00A787EE9FEF59)]


KEY & ROWS字段(优化重要信息)

possible_keys – 表示可能会用到的索引

此次查询中涉及字段上若存在索引,则会被列出来,表示可能会用到的索引,但并不是实际上一定会用到的索引

key – 实际使用的索引

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yjVuQjsk-1608014907486)(1BECE05AF9F342C1B4DF1AE49892E6F3)]

key_len – 表示索引中使用的字节数

通过该属性可以知道在查询中使用的索引长度,注意:这个长度是最大可能长度,并非实际使用长度,在不损失精确性的情况下,长度越短查询效率越高

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TdUnV5Co-1608014907487)(A9127FE393BD4278B72B40B09CD18192)]

rows–大致估算行数

根据表信息统计以及索引的使用情况,大致估算说要找到所需记录需要读取的行数,rows 越小越好


常见的优化手段

  • SQL语句中IN包含的值不应过多,不能超过200个,200个以内查询优化器计算成本时比较精准,超过200个是估算的成本,另外建议能用between就不要用in,这样就可以使用range索引了。
  • SELECT语句务必指明字段名称:SELECT * 增加很多不必要的消耗(cpu、io、内存、网络带宽);增加了使用覆盖索引的可能性;当表结构发生改变时,前断也需要更新。所以要求直接在select后面接上字段名。
  • 当只需要一条数据的时候,使用limit 1
  • 排序时注意是否能用到索引
  • 使用or时如果没有用到索引,可以改为union all 或者union
  • 如果in不能用到索引,可以改成exists看是否能用到索引
  • 使用合理的分页方式以提高分页的效率
  • 不建议使用%前缀模糊查询
  • 避免在where子句中对字段进行表达式操作
  • 避免隐式类型转换
  • 对于联合索引来说,要遵守最左前缀法则
  • 必要时可以使用force index来强制查询走某个索引
  • 对于联合索引来说,如果存在范围查询,比如between,>,<等条件时,会造成后面的索引字段失效。
  • 尽量使用inner join,避免left join,让查询优化器来自动选择小表作为驱动表
  • 必要时刻可以使用straight_join来指定驱动表,前提条件是本身是inner join

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值