顾名思义,运行时间较长的SQL即为慢SQL,多久算慢,如何定义?
SQL运行快慢是一个相对的概念,不同的业务场景下要求不同,慢SQL的标准也就不同。
MySQL中long_query_time参数定义了SQL运行阈值,默认为10s,可通过设置该阈值来调整基准。
参考:生产环境慢SQL一般设置为0.1~0.2s,但实际上会关注的慢sql一般>1s。
sql查询为什么会慢?我们先看一下sql的执行过程:
如上图所示,一条SQL语句执行时,分为以下几步:
MySQL执行过程中,优化器通过成本计算预估出执行效率最高的方式,以便执行器以最高效率执行SQL。 基本的成本预估维度为:I/O成本+CPU成本。
全表扫描成本计算:I/O成本+CPU成本
- I/O成本=页数 * 1.0(成本常数) + 1.1(微调数)
- CPU成本=数据行数 * 0.2(成本常数) + 1.0(微调数) 使用索引查询成本计算:I/O成本+CPU成本+回表I/O成本+回表CPU成本
- I/O成本=扫描区间 * 1.0(成本常数)
- CPU成本=数据行数 * 0.2(成本常数) + 0.01(微调数)
- 回表I/O成本=扫描区间 * 1.0(成本常数)
- 回表CPU成本=数据行数 * 0.2(成本常数) 注:mysql规定,当读取索引扫描的时候,每当读取一个扫描区间或者范围区间的IO成本,和读取一个页面的IO成本,是一样的,都是1.0。
基于以上两个维度我们可以得到影响SQL执行效率的关键在于I/O开销和CPU开销。哪些因素会影响到这两点呢?大致可总结以下几点:
影响MySQL各种类型的活动都会被记录在日志文件当中,常见的日志文件包括:
我们可以通过慢查询日志来查看慢SQL,默认情况下MySQL数据库不启动慢查询日志,需要手动将参数设置为:ON。
慢日志配置操作:
- 查看当前慢日志配置: 如上图所示:
- slow_quer_log:开关为ON,即打开状态。
- slow_query_log_file:慢日志文件写入地址。
- slow_query_log_always_write_time:定义了日志在查询结束后多久开始写。
- 开启慢日志配置:退出后重新连接即可生效。
MySQL提供了一个explain命令, 它可以对语句进行分析, 并输出执行的详细信息。
如上图所示:
列名 | 含义 |
---|---|
select_type | select子句类型 |
partitions | 匹配的分区 |
type | 访问类型,即怎么找数据行的方式(ALL, index,? range, ref, eq_ref, const, system, NULL) |
possible_keys | 能使用的索引 |
key | 预测使用的索引 |
key_len | 索引使用的字节数 |
ref | 连接匹配条件 |
rows | 估算出所查到的数据行数 |
filtered | 通过条件过滤出的行数所占百分比估计值,1~100,100表示没有做任何过滤 |
Extra | 该列包含MySQL解决查询的详细信息 |
通过explain命令,我们能分析出一些慢SQL的常见原因:
explain只能分析到SQL的预估执行计划,无法分析到SQL实际执行过程中的耗时,可以通过配置profiling参数来进行SQL执行分析。开启参数后,后续执行的SQL语句都会记录其资源开销,包括IO,上下文切换,CPU,Memory等等,我们可以根据这些开销进一步分析当前慢SQL的瓶颈再进一步进行优化。
我们可以通过查看SQL语句执行时每一个阶段的耗时,也可以通过命令查看完整列的执行情况。
列名 | 含义 |
---|---|
"Status" | 执行阶段 |
"Duration" | 持续时间 |
"CPU_user" | cpu用户 |
"CPU_system" | cpu系统 |
"Context_voluntary" | 上下文主动切换 |
"Context_involuntary" | 上下文被动切换 |
"Block_ops_in" | 阻塞的输入操作 |
"Block_ops_out" | 阻塞的输出操作 |
"Messages_sent" | 消息发出 |
"Messages_received" | 消息接收 |
"Page_faults_major" | 主分页错误 |
"Page_faults_minor" | 次分页错误 |
"Swaps" | 交换次数 |
"Source_function" | 源功能 |
"Source_file" | 源文件 |
"Source_line" | 源代码行 |
profile只能查看到SQL的执行耗时,但是无法看到SQL真正执行的过程信息。Optimizer Trace是一个跟踪功能,它可以跟踪执行语句的解析优化执行的全过程,可以开启该功能进行执行语句的分析。 诚如上述所说,explain只能判断出SQL预估的执行计划,预估时根据成本模型进行成本计算进而比较出理论最优执行计划,但在实际过程中,预估不代表完全正确,因此我们需要通过追踪来看到它在执行过程中的每一环是否真正准确。
在线客服
客服咨询
官方微信
返回顶部