如何索取有性能问题SQL的渠道
- 通过用户反馈获取存在性能问题的SQL
- 通过慢查日志获取存在性能问题的SQL
- 实时获取存在性能问题的SQL
慢查询日志介绍
- slow_quey_log=on 启动记录慢查询日志
- slow_query_log_file 指定慢查询日志的存储路径及文件(默认情况下保存在MySQL的数据目录中)
- long_query_time 指定记录慢查询日志sql执行的阈值(默认为10秒,通常改为0.001秒比较合适)
- log_queries_not_using_indexes 是否记录未使用索引的SQL
set global sql_query_log=on;
sysbench --test=./oltp.lua --mysql-table-engine=innodb --oltp-table-size=10000 --mysql-db=tests --mysql-user=sbtest --mysql-password=123456 --oltp-tables-count=10 --mysql-socket=/usr/local/mysql/data/mysql.sock run
慢查询日志分析工具
mysqldumpslow
- 汇总除查询条件外其它完全相同的SQL并将分析结果按照参数中所指定的顺序输出
mysqldumpslow -s r -t 10 slow-mysql.log
-s order(c,t,l,r,at,al,ar)[指定按照哪种排序方式输出结果]
1. c按照查询的次数排序
2. t按照查询的总时间排序
3. l按照查询中锁的时间来排序
4. r按照查询中返回总的数据行来排序
5. at、al、ar平均数量来排序-t top[指定取前几条作为结束输出]
pt-query-digest
pt-query-digest \
--explain h=127.0.0.1,u=root,p=p@ssWord \
slow-mysql.log
pt-query-digest –explain h=127.0.0.1 slow-mysql.log > slow.rep
实时获取存在性能问题的SQL
select id,user,host,db,command,time,state,info
FROM information_schema.processlist
WHERE time>=60
查询速度为什么会这麽慢?
- 客户端发送SQL请求给服务器
- 服务器检查是否可以在查询缓存中命中该SQL
- 服务器端进行SQL解析,预处理,再由优化器生成对应的执行计划
- 根据执行计划,调用存储引擎API来查询数据
- 将结果返回给客户端
》 对于一个读写频繁的系统使用查询缓存很可能会降低查询处理的效率,建议大家不要使用查询缓存
1 | 复制代码2.其中涉及的参数: |
如何确定查询处理各个阶段所消耗的时间
- 使用profile[不建议使用,未来mysql中将被移除]
1. set profiling = 1;[启动profile,这是一个session级别的配置]
2. 执行查询
3. show profiles;[查看每一个查询所消耗的总的时间的信息]
4. show profile for query N;[查询的每个阶段所消耗的时间]
5. show profile cpu for query N;[查看每个阶段所消耗的时间信息和所消耗的cpu的信息]
- 使用performance_schema
1. 启动所需要的监控和历史记录表的信息
> update setup\_instruments set enabled='yes',timed='yes' where name like 'stage%';
> update setup\_consumers set enabled='yes' where name like 'events%';
2. SELECT
a.thread\_id,
sql\_text,
c.event\_name,
(c.timer\_end - c.timer\_start) / 1000000000 AS 'duration(ms)'
FROM
events\_statements\_history\_long a
JOIN threads b on a.thread\_id=b.thread\_id
JOIN events\_stages\_history\_long c ON c.thread\_id=b.thread\_id
AND c.event\_id between a.event\_id and a.end\_event\_id
WHERE b.processlist\_id=CONNECTION\_ID()
AND a.event\_name='statement/sql/select'
ORDER BY a.thread\_id,c.event\_id
特定的SQL查询优化
- 大表的更新和删除
1 | 复制代码 delimiter ? |
- 如何修改大表的表结构
1.对表中的列的字段类型进行修改改变字段的宽度时还是会进行锁表
2.无法解决主从数据库延迟的问题
修改的方法:
1 | 复制代码 pt-online-schema-change |
- 如何优化not in和<>查询
1 | 复制代码 #原始的SQL语句 |
- 使用汇总表的方法进行优化
#统计商品的评论数(若有上亿条记录,执行起来非常慢进行全表扫描)[优化前的SQL]
select count(*) from product_comment where product_id=999;
1 | 复制代码 #汇总表就是提前以要统计的数据进行汇总并记录到数据库中以备后续的查询使用 |
本文转载自: 掘金