慢sql优化(一)

慢sql优化

慢SQL优化思路。

慢查询日志记录慢SQL

explain分析SQL的执行计划

profile 分析执行耗时

Optimizer Trace分析详情

确定问题并采用相应的措施

慢查询日志记录慢SQL

MySQL的慢查询,全名是慢查询日志,是MySQL提供的一种日志记录,用来记录在MySQL中响应时间超过阀值的语句。具体环境中,运行时间超过long_query_time值的SQL语句,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是记录运行10秒以上的语句。默认情况下,MySQL数据库并不启动慢查询日志,需要手动来设置这个参数。当然,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。
慢查询日志支持将日志记录写入文件和数据库表。

slow_query_log表示慢查询开启的状态

slow_query_log_file表示慢查询日志存放的位置

explain查看分析SQL的执行计划

当定位出查询效率低的SQL后,可以使用explain查看SQL的执行计划。

select_type

SIMPLE:简单SELECT(不适用UNION或子查询)
PRIMARY:最外面的select
UNION:UNION中的第二个或者后面的select语句
DEPENDENT UNION:UNION的第二个或者后面的select语句,取决于外面的查询
UNION RESULT:UNION的结果
SUBQUERY:子查询中第一个select
DEPENDENT SUBQUERY:子查询中第一个select,取决于外面的查询
DERIVED:导出表的select(FROM子句的子查询)

table

type

在这里插入图片描述

possible_keys

possible_keys列指出MySQL能使用哪个索引在该表中找到行。注意,该列完全独立于EXPLAIN输出所示的表的次序。这意味着在
possible_keys中的某些键实际上不能按生成的表次序使用。

key

key列显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在
查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

key_len

key_len列显示mysql决定使用的键长度,如果键是null,则长度为null

ref

ref列显示使用哪个列或常数与key一起从表中选择行

rows

rows列显示mysql认为它执行查询时必须检查的行数

Extra

在这里插入图片描述

profile 分析执行耗时

explain只是看到SQL的预估执行计划,如果要了解SQL真正的执行线程状态及消耗的时间,需要使用profiling。开启profiling参数后,后续执行的SQL语句都会记录其资源开销,包括IO,上下文切换,CPU,内存等等,我们可以根据这些开销进一步分析当前慢SQL的瓶颈再进一步进行优化

set profiling=ON开启
show profiles查看
show profile for query id (其中id就是show profiles中的QUERY_ID)查看具体一条的SQL语句分析
show profile cpu,block io for query id

Optimizer Trace分析详情

profile只能查看到SQL的执行耗时,但是无法看到SQL真正执行的过程信息,即不知道MySQL优化器是如何选择执行计划。这时候,我们可以使用Optimizer Trace,它可以跟踪执行语句的解析优化执行的全过程。

使用set optimizer_trace="enabled=on"打开开关,接着执行要跟踪的SQL,最后执行select * from information_schema.optimizer_trace跟踪
join_preparation:准备阶段

join_optimization:分析阶段

join_execution:执行阶段

确定问题并采用相应的措施

多数慢SQL都跟索引有关,比如不加索引,索引不生效、不合理等,这时候,我们可以优化索引。

我们还可以优化SQL语句,比如一些in元素过多问题(分批),深分页问题(基于上一次数据过滤等),进行时间分段查询

SQl没办法很好优化,可以改用ES的方式,或者数仓。

如果单表数据量过大导致慢查询,则可以考虑分库分表

如果数据库在刷脏页导致慢查询,考虑是否可以优化一些参数,跟DBA讨论优化方案

如果存量数据量太大,考虑是否可以让部分数据归档

如何优化group by
group by 后面的字段加索引

order by null 不用排序

尽量只使用内存临时表

使用SQL_BIG_RESULT

参考博文:
SQL太慢如何进行优化:https://blog.csdn.net/qq877192055/article/details/131321092
MySQL数据库基础知识3,mysql索引详解,上篇:https://blog.csdn.net/guorui_java/article/details/127189522

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值