查询慢查询日志
Mysql性能分析和优化
性能分析,优化,监控工具
1.性能分析
慢查询日志,profile性能监控,performance_schema性能监控
1.1慢查询日志
分析:
- 通过慢查询日志获取查询时间较长的SQL
- 查看SQL的执行计划explain
- 使用show profile[s] 查看SQL的性能使用情况
注意:开启慢查询日志影响mysql性能,排查问题时再开启。
1.1.1开启慢查询日志
连接服务器
工具:FinalShell
登录mysql
慢查询日志
- 开启
- 设置参数
查看慢查询日志
查看慢查询信息
1 | ## 登录mysql |
慢查询设置(开启、收集条件)
临时
重启失效
1 | ## 开启 |
永久
修改配置文件
1 | my.cnf |
1.1.2分析慢查询日志
mysqldumpslow工具
mysql自带
1 | # 按照查询时间排序的前10条里面含有左连接的查询语句 |
1 | -s 表示按照何种方式排序 |
percona-toolkit工具
安装
1 | yum -y install perl-DBD-MySQL |
分析
1 | # 执行工具pt-query-digest |
常用命令
分析慢查询文件
1
pt-query-digest slow.log > slow_report.log
报告:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112第一部分
该工具执行日志分析的用户时间,系统时间,物理内存占用大小,虚拟内存占用大小
# 95.2s user time, 1.9s system time, 1.09G rss, 1.17G vsz
工具执行时间
# Current date: Thu Jun 10 16:45:43 2021
运行分析工具的主机名
# Hostname: iZbp15xr4imyrogpz1216f9Z
被分析的文件名
# Files: /usr/lib/mysql/slow.log
语句总数量,唯一的语句数量,QPS,并发数
# Overall: 38.97k total, 321 unique, 0.03 QPS, 0.06x concurrency _________
日志记录的时间范围
# Time range: 2021-05-25T07:31:57 to 2021-06-10T08:45:02
# Attribute total min max avg 95% stddev median
# ============ ======= ======= ======= ======= ======= ======= =======
# Exec time 76953s 1s 467s 2s 3s 9s 1s
# Lock time 729s 0 29s 19ms 214us 546ms 119us
# Rows sent 98.47M 0 1.68M 2.59k 0.99 46.83k 0.99
# Rows examine 57.71G 0 1.69M 1.52M 1.61M 303.67k 1.53M
# Query size 1.34G 6 29.15M 35.96k 84.10 477.84k 84.10
第二部分
# Profile
Rank:所有语句的排名,默认按查询时间降序排列,通过--order-by指定
Query ID:语句的ID,(去掉多余空格和文本字符,计算hash值)
Response:总的响应时间
time:该查询在本次分析中总的时间占比
calls:执行次数,即本次分析总共有多少条这种类型的查询语句
R/Call:平均每次执行的响应时间
V/M:响应时间Variance-to-mean的比率
Item:查询对象
# Rank Query ID Response time Calls R/Call V/M
# ==== =============================== =============== ===== ====== =====
# 1 0xABD1DCCCCD5AA5128E10C27B34... 1246.6948 41.7% 283 4.4053 0.04 UPDATE ziweidashi_deviceinfo
# 2 0x6914B81AAD1785E50708ABD113... 877.6900 29.3% 339 2.5891 0.09 SELECT birthDay_notify
# 3 0x44D9474C6D5C58DD07B5FEEA0D... 299.4193 10.0% 71 4.2172 0.05 SELECT tmall_product_orders
# 4 0xA9BE84CBE3DAA9B1CDD9B5A9EC... 127.0137 4.2% 46 2.7612 0.04 SELECT daily_user_action_log
# 5 0xCF0E12117C971C3013142E3717... 118.3138 4.0% 49 2.4146 0.05 SELECT tmall_user_take_coupon_record
# 6 0x94263184D24186330B13193534... 97.0805 3.2% 35 2.7737 0.56 SELECT tgg_users
# 7 0xC51165F1287A2ECDA221AC1F54... 52.5870 1.8% 22 2.3903 0.04 SELECT util_user_task_log
# 8 0xB8004D6D8A7A7967E04CD81E26... 43.7895 1.5% 16 2.7368 0.08 SELECT daily_user_action_log
# 9 0x910E19224F33DAA6391927B8E8... 41.3720 1.4% 15 2.7581 1.17 SELECT qifugong_tianbi_record
# MISC 0xMISC 86.7871 2.9% 30 2.8929 0.0 <12 ITEMS>
第三及后续部分,第一条查询语句 query id:0xABD1DCCCCD5AA5128E10C27B34BC04E7
# Query 1: 0.01 QPS, 0.03x concurrency, ID 0xABD1DCCCCD5AA5128E10C27B34BC04E7 at byte 355748
# Scores: V/M = 0.04
# Time range: 2020-03-11 12:24:03 to 2020-03-12 00:16:13
# Attribute pct total min max avg 95% stddev median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count 31 283
# Exec time 41 1247s 4s 8s 4s 5s 437ms 4s
# Lock time 69 386ms 24us 371ms 1ms 93us 21ms 44us
# Rows sent 0 0 0 0 0 0 0 0
# Rows examine 18 180.00M 651.14k 651.45k 651.29k 650.62k 0 650.62k
# Query size 10 27.64k 100 100 100 100 0 100
# String:
数据库名
# Databases taxen_ziweidashi
执行主机
# Hosts 118.190.93.166
执行用户
# Users devAccount
查询时间占比
# Query_time distribution
# 1us
# 10us
# 100us
# 1ms
# 10ms
# 100ms
# 1s ################################################################
# 10s+
# Tables
# SHOW TABLE STATUS FROM `taxen_ziweidashi` LIKE 'ziweidashi_deviceinfo'
# SHOW CREATE TABLE `taxen_ziweidashi`.`ziweidashi_deviceinfo`
UPDATE ziweidashi_deviceinfo
SET expired = 1
WHERE createTime <= 1583942580685\G
# Converted for EXPLAIN
# EXPLAIN /*!50100 PARTITIONS*/
select expired = 1 from ziweidashi_deviceinfo where createTime <= 1583942580685\G
# Query 2: 0.03 QPS, 0.07x concurrency, ID 0x6914B81AAD1785E50708ABD11319E02E at byte 13829
# Scores: V/M = 0.09
# Time range: 2020-03-11 12:22:13 to 16:05:47
# Attribute pct total min max avg 95% stddev median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count 37 339
# Exec time 29 878s 2s 4s 3s 4s 472ms 2s
# Lock time 5 29ms 31us 4ms 86us 98us 229us 66us
# Rows sent 0 24 0 2 0.07 0 0.32 0
# Rows examine 67 665.20M 1.96M 1.96M 1.96M 1.96M 0 1.96M
# Query size 59 154.47k 462 467 466.60 463.90 2.07 463.90
# String:
# Hosts 10.66.186.115
# Users root
# Query_time distribution
# 1us
# 10us
# 100us
# 1ms
# 10ms
# 100ms
# 1s ################################################################
# 10s+
# Tables
# SHOW TABLE STATUS LIKE 'birthDay_notify'
# SHOW CREATE TABLE `birthDay_notify`
# EXPLAIN /*!50100 PARTITIONS*/
select birthdayno0_.id as id1_1_, birthdayno0_.index_card_show_date as index_ca2_1_, birthdayno0_.userId as userId3_1_, birthdayno0_.push_content as push_con4_1_, birthdayno0_.card_content as card_con5_1_, birthdayno0_.birthday_userId as birthday6_1_, birthdayno0_.birthday_contactId as birthday7_1_, birthdayno0_.need_push as need_pus8_1_ from birthDay_notify birthdayno0_ where birthdayno0_.userId=1304747 and birthdayno0_.index_card_show_date='2020-03-11 00:00:00'分析最近12小时内的查询
1
pt-query-digest --since=12h slow.log > slow_report_last12.log
分析制定时间范围内的查询
1
pt-query-digest slow.log --since '2017-02-07 09:30:00' --until '2017-02-07 10:00:00'> > slow_report_time.log
分析bin log
1
2mysqlbinlog mysql-bin.000093 > mysql-bin000093.sql
pt-query-digest --type=binlog mysql-bin000093.sql > slow_report_bin.log分析general log
1
pt-query-digest --type=genlog localhost.log > slow_report_general.log
1.2profile性能监控
MySQL5.6中已过时,使用performance_schema代替。13.7.5.31 SHOW PROFILE Statement
1.3performance_schema性能监控
参考:MySql8.027.19.1 Query Profiling Using Performance Schema
SQL在各阶段的耗时分析,默认开启
查看是否开启
SHOW VARIABLES LIKE ‘performance_schema’;
开启
1 | # my.cnf |
修改performance_schema监控配置,并分析一个测试SQL
1 | # 查看performance_schema是否开启 |
2.优化
表和字段结构设计,索引,SQL语句,Mysql配置,操作系统配置,硬件,内存预热
开发人员关注表结构设计、索引和SQL语句方面的优化。
DBA学习Mysql配置,操作系统配置,硬件
2.1表和字段结构设计
减少关联查询,创建合理的冗余字段
字段太多的大表,拆表
表中不常用的字段或者存储数据比较多的字段,拆表。(商品表中的商品介绍字段单独拆解到另一个表中,使用ID关联)
每张表都要有主键,主键最好是int类型。
字段数据类型优先选用较小的数据结构。
例如:年龄使用TINYINT,而不是INT
日期类型使用int类型,日期排序以及对比等操作的效率会更高
2.2索引
数量不要超过6个。通过索引返回的数据量需要小于1/3才有效。
建立索引
- on两边,where字段
- 组合索引(最左前缀)
- order排序
- group by分组统计
避免失效
- or,is null,is not null
- between右边
- where 子句中的“=”左边进行函数、算术运算或其他表达式运算
- 不遵循组合索引最左前缀
- 字符串不加’’(单引号)
- like (%abc),可通过组合索引解决
2.3SQL语句
SQL分析,SQL注意点
2.3.1SQL分析
SQL的执行计划explain,使用show profile[s] 查看SQL的性能使用情况
explian 详见Mysql索引
实例
- asdf
1
2
3
4
5
6
7
8
9
10
11Count: 36240 Time=1.20s (43521s) Lock=0.00s (4s) Rows=1.0 (36240), root[root]@4hosts
select IFNULL(max(zkkq_id), 1) from attendance_card;
# attendance_card本身是有序的,从小到大
# 优化 速度:1.2→0.1
select ifnull( zkkq_id,1) from attendance_card order by id desc limit 1;
# 判断表是否为空
# 100万 0.6s
select count(*) from table
# 100万 0.01s
select 1 from logmgr_log_history limit 1 - 索引失效。or、order by id limitor 导致branch_code失效。
1
WHERE (branch_code = ? OR branch_name LIKE concat(?, ?, ?)) AND create_time >= ? AND create_time <= ? ORDER BY id DESC LIMIT ?
order by id desc limit 20 使create_time失效,而使用了id
2.3.2SQL优化
避免select *
日期条件字段使用bigint,存储时间戳
left join on 后不加and, where 后加and
表索引多,没有走正确的索引时,user index(index_user_id) ,强制走索引
左连接注意SQL执行顺序,mysql会做优化,小表驱动大表,也可自己优化
limit
有截断效果(停止全表扫描),但还是在server层处理数据
1
2
3
4
5一千万条数据
# 速度很慢 10
select * from user limit 9000000 for 10
# 速度很快 0.03
select * from user where id > 9000000 limit 10count
count(*)找普通索引,即去最小的索引树遍历,包含nullcount(字段) ,走缓存,不包含null
count(1) 包含null
exists
尽量使用NOT EXISTS替代NOT IN,使用EXISTS替代DISTINCT。1
2
3
4
5
6
7
8
9
10SELECT DISTINCT r.*
FROM task r
LEFT JOINtask_sku_box box ON r.rece_id = box.rece_id
WHERE box.sku_code = '1111';
explain SELECT r.*
FROM task r
where exists(
select 1 from task_sku_box box where r.rece_id = box.rece_id and sku_code = '1111'
);sql索引字段上尽量不要使用函数,在Java中计算好,直接传入。
1
select * from user where create_time > now() -1
1
2// 当前时间前三个月
LocalDateTime threeMonthsAgo = LocalDateTime.now().minusMonths(3);
2.4Mysql配置
Buffer Pool
默认128M,修改为系统内存的4/5,尽量从内存中读取。
buffer pool越大和存储引擎I/O次数越少。
1 | mysql> show global status like 'innodb_buffer_pool_pages_%'; |
1 | # 修改配置 my.cnf |
redo log file
默认8M,修改为Buffer的1/4.降低磁盘写入次数。
1 | innodb_log_file_size = 750M |
2.5操作系统设置
2.6硬件
固态硬盘
2.7内存预热
mysql监控工具
收费:阿里云
免费:druid连接池