基础
MySQL
MySQL
  • 基础知识
    • MySQL 的安装与配置
      • Windows
        • 安装
        • 配置文件
      • Linux
        • 安装
        • 配置文件
      • docker
      • mysql 配置文件格式
    • MySQL 查询的执行过程
      • MySQL 的客户端/服务器通信协议
      • MySQL 查询优化器
        • 优化器可能选择错误的执行计划
        • MySQL 能够处理的优化类型
          • 优化 COUNT()、MIN() 和 MAX()
          • 预估并转化为常数表达式
          • 提前终止查询
          • 排序优化
      • MySQL如何执行联接查询
    • 事务
      • ACID
      • 隔离级别
      • 死锁
      • 事务日志
      • 两阶段锁定协议
      • 多版本并发控制(MVCC)
  • SQL 优化
    • schema 设计
      • 选择数据类型
        • 整数类型
        • 实数类型
        • 字符串类型
          • VARCHAR 和 CHAR
          • BINARY 和 VARBINARY
          • BLOB 和 TEXT
          • ENUM 和 SET
        • 日期类型
      • 选择标识符
    • 索引
      • HASH 索引
      • B-tree 索引
      • 聚簇索引
      • 覆盖索引
      • 前缀索引和索引的选择性
      • 索引合并
      • 选择合适的索引列顺序
      • 使用索引扫描来做排序
      • 维护索引和表
    • 查询优化
      • 优化 SQL 语句的一般步骤
        • 1. 通过 show status 命令了解各种 SQL 的执行频率
        • 2. 定位执行效率较低的 SQL 语句
        • 3. 通过 EXPLAIN 分析低效 SQL 的执行计划
        • 4. 通过 SHOW PROFILE 分析 SQL
        • 5. 通过 TRACE 分析优化器如何选择执行计划
        • 6. 确定问题并采取相应的优化措施
      • 两个简单实用的优化方法
      • 一个复杂查询还是多个简单查询
      • 常用 SQL 的优化
        • 大批量插入数据
        • 优化 GROUP BY 语句
        • 优化联接查询
        • 优化分页查询
        • 优化 SQL_CALC_FOUND_ROWS
        • 优化 UNION 查询
    • Performance Schema
      • 配置
      • 使用
        • 检查SQL语句
        • 检查预处理语句
        • 语句剖析
        • 检查读写性能
        • 检查内存使用情况
        • 检查变量
    • MySQL线程
    • 复制
      • 概述
        • 复制中的各类文件
        • 三种复制格式
        • 全局事务标识符(GTID)
        • 崩溃后的复制安全
      • 安装
        • 基于二进制日志文件位置的复制
        • 基于GTID的复制
      • 复制拓扑
        • 主动/被动模式
        • 主动/只读池模式
        • 多级复制架构
  • 其他
    • 查询缓存
    • 批量insert
    • MySQL 锁的类型
    • MySQL 的索引有哪些
    • INSERT ... ON DUPLICATE KEY UPDATE Statement
由 GitBook 提供支持
在本页
  • 1. 启用插桩
  • 2. 启用消费者表
  • 3. 查询消费者表,找出需要优化的SQL语句
  • 找到所有没有使用合适索引的查询
  • 找出所有创建了临时表的查询
  • 找出所有返回错误的查询
  • 找出所有执行时间超过 5 秒的查询
  • 4. 使用sys Schema
  1. SQL 优化
  2. Performance Schema
  3. 使用

检查SQL语句

上一页使用下一页检查预处理语句

最后更新于1年前

1. 启用插桩

要启用语句检测,需要启用statement类型的插桩(默认已经启用)

UPDATE setup_instruments
SET enabled = 'YES'
WHERE name LIKE 'statement/%'
  AND enabled = 'NO';

相关的插桩如下表:

插桩类
描述
插桩类
描述
插桩类
描述
插桩类
描述
插桩类
描述

2. 启用消费者表

Performance Schema将语句指标存储在 events_statements_current、events_statements_history 和 events_statements_history_long 表中。因此,接着需要启用(enable)这三张消费者表:

UPDATE setup_consumers
SET enabled = 'YES'
WHERE name LIKE 'events_statements_%'
  AND enabled = 'NO';

在5.7版本中, events_statements_current、events_statements_history 默认处于enabled状态,events_statements_history_long 则处于disabled状态。

3. 查询消费者表,找出需要优化的SQL语句

在 events_statements_history 表中可以作为优化指标的列如下:

列
描述
重要性

CREATED_TMP_DISK_TABLES

查询创建的临时磁盘表的数量。

高

CREATED_TMP_TABLES

查询创建的临时表的数量。

中

SELECT_FULL_JOIN

因为没有合适的索引,所以导致JOIN执行了全表扫描。

高

SELECT_FULL_RANGE_JOIN

JOIN操作是否使用了被引用表的范围搜索。

中

SELECT_RANGE

JOIN操作是否使用了范围搜索来解析第一个表中的行。

低

SELECT_RANGE_CHECK

如果JOIN操作没有索引,则会检查每一行之后的键。 这是一种非常糟糕的症状,如果该值大于零,则需要重新考虑表中的索引设计。

高

SELECT_SCAN

JOIN操作是否对第一个表执行了全表扫描。 如果第一个表很大则会使一个问题。

中

SORT_MERGE_PASSES

排序必须执行的合并过程数。 如果该值大于零且查询性能较低,则可能需要增加 sort_buffer_size 的值。

低

SORT_RANGE

是否使用的是范围排序。

低

SORT_ROWS

排序的行数。 如果排序的行数比返回的行数多,则可能需要优化查询。

中

SORT_SCAN

排序是否是通过扫描表完成的。 这是一个非常糟糕的迹象,除非有意选择表中的所有行而不使用索引。

高

NO_INDEX_USED

查询没有使用索引。

高

NO_GOOD_INDEX_USED

查询所用的索引不是最合适的。 如果该值大于零,则需要重新考虑索引的设计。

高

要找出哪些语句需要优化,可以选择上述列中的任何一列,并将其与 0 进行比较。

找到所有没有使用合适索引的查询

SELECT
    thread_id,
    sql_text,
    rows_sent,
    rows_examined,
    created_tmp_disk_tables,
    created_tmp_tables,
    no_index_used,
    no_good_index_used
FROM events_statements_history
WHERE no_index_used > 0
   OR no_good_index_used > 0;

找出所有创建了临时表的查询

SELECT
    thread_id,
    sql_text,
    rows_sent,
    rows_examined,
    created_tmp_disk_tables,
    created_tmp_tables,
    no_index_used,
    no_good_index_used
FROM events_statements_history
WHERE created_tmp_disk_tables > 0
   OR created_tmp_tables > 0;

找出所有返回错误的查询

SELECT
    thread_id,
    sql_text,
    mysql_errno,
    returned_sqlstate,
    message_text,
    errors
FROM events_statements_history
WHERE errors > 0;

找出所有执行时间超过 5 秒的查询

SELECT
    *
FROM events_statements_history
WHERE timer_wait > 5000000000;

4. 使用sys Schema

sys schema提供了可用于查找有问题语句的视图,如下表所示:

视图
描述

statement_analysis

具有聚合统计信息的规范化语句视图,按每个规范化语句的总执行时间进行排序。

类似于 events_statements_summary_by_digest表,但没有那么详细。

statements_with_errors_or_warnings

所有引起错误或警告的规范化语句。

statements_with_full_table_scans

所有执行了全表扫描的规范化语句。

statements_with_runtimes_in_95th_percentile

所有平均执行时间在前 95% 的规范化语句。

statements_with_sorting

所有执行了排序的规范化语句。

statements_with_temp_tables

所有使用了临时表的规范化语句。

sys schema 使用摘要文本而不是查询文本,因此你将获得查询文本的摘要,而不是像直接访问Performance Schema那样获得的要么是SQL语句要么是摘要文本:

SELECT
    query
FROM sys.statements_with_temp_tables
WHERE db = 'sakila'
  AND query LIKE '% ORDER BY %';
  
+-----------------------------------------------------------------+
|query                                                            |
+-----------------------------------------------------------------+
|EXPLAIN SELECT `payment_date`  ...  BY `payment_date` ORDER BY ? |
+-----------------------------------------------------------------+

statement/sql

SQL语句,如 SELECT、CREATE TABLE等

statement/sp

存储过程控制

statement/scheduler

事件调度器

statement/com

命令,如 quit、kill、DROP DATABASE、Binlog Dump等 有些命令是用户不可用的,只能由 mysqld 进程调用

statement/abstract

包括 4 类命令:clone、Query、new_packet 和 relay_log