mysql分析慢查询语句_mysql慢查询语句分析总结

我们经常会接触到MySQL,也经常会遇到一些MySQL的性能问题。我们可以借助慢查询日志和explain命令初步分析出SQL语句存在的性能问题

通过SHOW FULL PROCESSLIST查看问题

SHOW FULL PROCESSLIST相当于select * from information_schema.processlist可以列出正在运行的连接线程,

474ac19f75176543cd24960373960f15.png

processlist

说明:id 连接id,可以使用kill+连接id的方式关闭连接(kill 9339)

user显示当前用户

host显示连接的客户端IP和端口

db显示进程连接的数据库

command显示当前连接的当前执行的状态,sleep、query、connect

time显示当前状态持续的时间(秒)

state显示当前连接的sql语句的执行状态,copying to tmp table、sorting result、sending data等

info显示sql语句,如果发现比较耗时的语句可以复制出来使用explain分析。

慢查询日志

慢查询日志是MySQL用于记录响应时间超过设置阈值(long_query_time)的SQL语句,默认情况下未开启慢查询日志,需要手动配置。

下面我们要记住几个常用的属性:slow_query_log:是否开启慢查询(ON为开启,OFF则为关闭)

long_query_time:慢查询阀值,表示SQL语句执行时间超过这个值就会记录,默认为10s

slow_query_log_file:慢查询日志存储的文件路径

log_queries_not_using_indexes: 记录没有使用索引查询语句(ON为开启,OFF为关闭)

log_output:日志存储方式(FILE表示将日志写入文件,TABLE表示写入数据库中,默认值为FILE,如果存入数据库中,我们可以通过select * from mysql.slow_log的方式去查询,一般性能要求相对较高的建议存文件)

我们可以通过show variables like ‘%关键字%’的方式查询我们设置的属性值

88109714d3fae161bfc6c55f3ea0cd22.png

slow

我们有两种方式设置我们的属性,一种是set global 属性=值的方式(重启失效),另一种是配置文件(重启生效)

命令方式:

set global slow_query_log=1;

set global long_query_time=1;

set global slow_query_log_file='mysql-slow.log'

配置文件方式:

slow_query_log = 'ON'

slow_query_log_file = D:/Tools/mysql-8.0.16/slow.log

long_query_time = 1

log-queries-not-using-indexes

pt-qurey-digest分析慢查询语句

percona-toolkit包含了很多实用强大的mysql工具包,pt-qurey-digest只是其中一个用于分析慢查询日志是工具。需要去官网下载,使用方法也很简单:

./pt-query-digest slow2.log >> slow2.txt

即可得出一个分析结果:

# Query 9: 0.00 QPS, 0.00x concurrency, ID 0xF914D8CC2938CE6CAA13F8E57DF04B2F at byte 499246

# This item is included in the report because it matches --limit.

# Scores: V/M = 0.22

# Time range: 2019-07-08T03:56:12 to 2019-07-12T00:46:28

# Attribute pct total min max avg 95% stddev median

# ============ === ======= ======= ======= ======= ======= ======= =======

# Count 8 69

# Exec time 1 147s 1s 3s 2s 3s 685ms 2s

# Lock time 0 140ms 2ms 22ms 2ms 3ms 2ms 2ms

# Rows sent 0 0 0 0 0 0 0 0

# Rows examine 0 23.96M 225.33k 482.77k 355.65k 462.39k 81.66k 345.04k

# Query size 2 17.72k 263 263 263 263 0 263

# String:

# Databases xxxx

# Hosts xx.xxx.xxx.xxx

# Users root

# Query_time distribution

# 1us

# 10us

# 100us

# 1ms

# 10ms

# 100ms

# 1s ################################################################

# 10s+

# Tables

# SHOW TABLE STATUS FROM `xxxx` LIKE 'xxxxx_track_exec_channel'G

# SHOW CREATE TABLE `xxxx`.`xxxxxxxx_exec_channel`G

# SHOW TABLE STATUS FROM `xxx` LIKE 'xxxxx_TRACK_ASSIGN'G

# SHOW CREATE TABLE `xxxx`.`xxxxx_EFFECTIVE_TRACK_ASSIGN`G

# SHOW TABLE STATUS FROM `xxx` LIKE 'xxxx_task_exec'G

# SHOW CREATE TABLE `xxxx`.`xxxxx_task_exec`G

UPDATExxxxxx_effective_track_exec_channel a

SET EXEC_CHANNEL_CODE=(SELECT GROUP_CONCAT(DISTINCT(channel_id)) FROM xxxxxx_EFFECTIVE_TRACK_ASSIGN WHERE status in (1,2,4) AND id IN (SELECT assgin_id FROM xxxxxx_task_exec WHERE task_id=a.task_id))G

explain分析SQL语句

上面几点大概的介绍到了几种获取慢查询SQL语句的方式,现在,我们就需要借助explain来分析查找SQL语句慢的原因。explain使用也很简单,直接在SELECT|UPDATE等语句前加上EXPLAIN即可

facd803f7334f1dc0f66630bdc6bc805.png

explain

id

表的执行顺序,复制的sql语句往往会分为很多步,序号越大越先执行,id相同执行顺序从上往下

select_type

数据读取操作的操作类型:SIMPLE(简单SELECT,不使用UNION或子查询等)

PRIMARY(子查询中最外层查询,查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY)

UNION(UNION中的第二个或后面的SELECT语句)

DEPENDENT UNION(UNION中的第二个或后面的SELECT语句,取决于外面的查询)

UNION RESULT(UNION的结果,union语句中第二个select开始后面所有select)

SUBQUERY(子查询中的第一个SELECT,结果不依赖于外部查询)

DEPENDENT SUBQUERY(子查询中的第一个SELECT,依赖于外部查询)

DERIVED(派生表的SELECT, FROM子句的子查询)

UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)

table

数据来源于那张表,关联等复杂查询时会用临时虚拟表

type

检索数据的方式system:表只有一行记录

const:通过索引查找并且一次性找到

eq_ref:唯一性索引扫描

ref:非唯一行索引扫描

range:按范围查找

index:遍历索引树

all:全表扫描

possible_keys

显示可能使用的索引

Key

实际使用的索引

key_len

索引的长度,一般来说,长度越短越好

ref

列与索引的比较,表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

rows

估算查找的结果记录条数

Extra

SQL查询的详细信息Using where:表示使用where条件过滤

Using temporary:使用了临时表暂存结果

Using filesort:说明mysql对数据使用一个外部索引排序。未按照表内的索引顺序进行读取。

Using index:表示select语句中使用了覆盖索引,直接从索引中取值

Using join buffer:使用了连接缓存

Using index condition:表示查询的列有非索引的列

[参考]

MySQL Explain详解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于优化 MySQL 查询的 SQL 语句,可以考虑以下几个方面: 1. 使用索引:确保表中的列上有适当的索引。通过分析查询执行计划,可以确定哪些索引被使用或未使用,并根据需要添加或修改索引。 2. 优化查询语句:检查查询语句是否可以优化。避免使用不必要的连接操作,使用合适的 JOIN 类型,避免使用过多的子查询或临时表。 3. 限制结果集大小:如果查询结果集非常大,但实际只需要部分结果,可以使用 LIMIT 关键字限制返回的行数。 4. 分页查询优化:对于需要分页的查询,尽量避免使用 OFFSET 关键字,它会导致 MySQL 跳过大量的行。可以使用游标或者优化查询语句结构来提高性能。 5. 缓存查询结果:对于经常被重复执行的查询,可以考虑使用缓存技术,如 Redis 或 Memcached。将查询结果缓存在内存中,可以减少对数据库的访问次数。 6. 查询字段优化:只选择需要的字段,避免不必要的数据传输和存储开销。可以使用 SELECT 指定具体字段,而不是使用 SELECT *。 7. 优化表结构:合理设计数据库表结构,避免冗余和不必要的复杂性。对于大型表,可以考虑分区、分表等技术来提高查询性能。 8. 定期优化和维护:定期分析数据库性能,并进行优化和维护操作,如重新生成索引、收集统计信息、清理无用数据等。 以上是一些常见的优化方法,根据具体情况选择适合的优化策略。可以通过 MySQL 的 EXPLAIN 关键字分析查询执行计划,找出查询的原因,并根据需要进行相应的优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值