📣

TiDB Cloud Serverless 现已更名为
Starter
!此页面由 AI 自动翻译,英文原文请见
此处。

语句概要表

为更好地处理 SQL 性能问题,MySQL 在 performance_schema 中提供了 statement summary tables(语句概要表),用于通过统计信息监控 SQL。在这些表中,events_statements_summary_by_digest 表通过其丰富的字段(如延迟、执行次数、扫描行数、全表扫描等)在定位 SQL 问题时非常有用。

因此,从 v4.0.0-rc.1 版本开始,TiDB 在 information_schema不是 performance_schema)中提供了与 events_statements_summary_by_digest 功能类似的系统表。

本文档详细介绍了这些表,并介绍如何使用它们来排查 SQL 性能问题。

statements_summary

statements_summaryinformation_schema 下的一个系统表。statements_summary 按资源组、SQL 摘要(digest)和执行计划摘要(plan digest)对 SQL 语句进行分组,并为每类 SQL 提供统计信息。

这里的 “SQL 摘要” 与慢日志中的含义一致,是通过标准化 SQL 语句计算得到的唯一标识。标准化过程会忽略常量、空白字符,并且不区分大小写。因此,语法一致的语句会有相同的摘要。例如:

SELECT * FROM employee WHERE id IN (1, 2, 3) AND salary BETWEEN 1000 AND 2000; select * from EMPLOYEE where ID in (4, 5) and SALARY between 3000 and 4000;

标准化后,它们都属于如下类别:

select * from employee where id in (...) and salary between ? and ?;

“执行计划摘要”是指通过标准化执行计划计算得到的唯一标识。标准化过程会忽略常量。相同的 SQL 语句可能会因为执行计划不同而被分到不同的类别。属于同一类别的 SQL 语句具有相同的执行计划。

statements_summary 存储了 SQL 监控指标的聚合结果。一般来说,每个监控指标都包含最大值和平均值。例如,执行延迟指标对应两个字段:AVG_LATENCY(平均延迟)和 MAX_LATENCY(最大延迟)。

为保证监控指标的实时性,statements_summary 表中的数据会定期清理,仅保留和展示最近的聚合结果。定期清理数据的周期由系统变量 tidb_stmt_summary_refresh_interval 控制。如果你在清理后立即查询,显示的数据可能会很少。

以下是查询 statements_summary 的示例输出:

SUMMARY_BEGIN_TIME: 2020-01-02 11:00:00 SUMMARY_END_TIME: 2020-01-02 11:30:00 STMT_TYPE: Select SCHEMA_NAME: test DIGEST: 0611cc2fe792f8c146cc97d39b31d9562014cf15f8d41f23a4938ca341f54182 DIGEST_TEXT: select * from employee where id = ? TABLE_NAMES: test.employee INDEX_NAMES: NULL SAMPLE_USER: root EXEC_COUNT: 3 SUM_LATENCY: 1035161 MAX_LATENCY: 399594 MIN_LATENCY: 301353 AVG_LATENCY: 345053 AVG_PARSE_LATENCY: 57000 MAX_PARSE_LATENCY: 57000 AVG_COMPILE_LATENCY: 175458 MAX_COMPILE_LATENCY: 175458 ........... AVG_MEM: 103 MAX_MEM: 103 AVG_DISK: 65535 MAX_DISK: 65535 AVG_AFFECTED_ROWS: 0 FIRST_SEEN: 2020-01-02 11:12:54 LAST_SEEN: 2020-01-02 11:25:24 QUERY_SAMPLE_TEXT: select * from employee where id=3100 PREV_SAMPLE_TEXT: PLAN_DIGEST: f415b8d52640b535b9b12a9c148a8630d2c6d59e419aad29397842e32e8e5de3 PLAN: Point_Get_1 root 1 table:employee, handle:3100

statements_summary_history

statements_summary_history 的表结构与 statements_summary 完全一致。statements_summary_history 保存了一段时间范围内的历史数据。通过查看历史数据,你可以排查异常并对比不同时段的监控指标。

SUMMARY_BEGIN_TIMESUMMARY_END_TIME 字段分别表示历史时间段的起始和结束时间。

statements_summary_evicted

tidb_stmt_summary_max_stmt_count 系统变量限制了 statements_summarystatements_summary_history 两张表在内存中总共能存储的 SQL 摘要数量。当超过该限制时,TiDB 会从 statements_summarystatements_summary_history 表中淘汰最久未使用的 SQL 摘要。

statements_summary_evicted 表记录了发生淘汰的时间段以及该时间段内被淘汰的 SQL 摘要数量。该表可以帮助你评估 tidb_stmt_summary_max_stmt_count 是否配置合理。如果该表有记录,说明某一时刻 SQL 摘要数量超过了 tidb_stmt_summary_max_stmt_count

诊断页面的 SQL 语句标签页 中,被淘汰语句的信息会显示在 Others 行。

语句概要的 cluster

statements_summarystatements_summary_historystatements_summary_evicted 只展示单个 TiDB 实例的语句概要。要查询整个集群的数据,需要查询 cluster_statements_summarycluster_statements_summary_historycluster_statements_summary_evicted 表。

cluster_statements_summary 展示每个 TiDB 实例的 statements_summary 数据。cluster_statements_summary_history 展示每个 TiDB 实例的 statements_summary_history 数据。cluster_statements_summary_evicted 展示每个 TiDB 实例的 statements_summary_evicted 数据。这些表通过 INSTANCE 字段表示 TiDB 实例的地址,其他字段与 statements_summarystatements_summary_historystatements_summary_evicted 相同。

参数配置

以下系统变量用于控制语句概要功能:

  • tidb_enable_stmt_summary:是否开启语句概要功能。1 表示开启,0 表示关闭。默认开启。关闭后系统表中的统计信息会被清空;下次开启时会重新统计。测试表明开启该功能对性能影响很小。

  • tidb_stmt_summary_refresh_intervalstatements_summary 表的刷新周期,单位为秒(s),默认值为 1800

  • tidb_stmt_summary_history_sizestatements_summary_history 表中每类 SQL 语句存储的历史周期数,也是 statements_summary_evicted 表的最大记录数。默认值为 24

  • tidb_stmt_summary_max_stmt_count:限制 statements_summarystatements_summary_history 两张表在内存中总共能存储的 SQL 摘要数量。默认值为 3000

    当超过该限制时,TiDB 会从 statements_summarystatements_summary_history 表中淘汰最久未使用的 SQL 摘要。这些被淘汰的摘要会被计入 statements_summary_evicted 表。

  • tidb_stmt_summary_max_sql_length:指定 DIGEST_TEXTQUERY_SAMPLE_TEXT 的最大显示长度。默认值为 4096

  • tidb_stmt_summary_internal_query:是否统计 TiDB 内部 SQL 语句。1 表示统计,0 表示不统计。默认值为 0

语句概要配置示例如下:

set global tidb_stmt_summary_max_stmt_count = 3000; set global tidb_enable_stmt_summary = true; set global tidb_stmt_summary_refresh_interval = 1800; set global tidb_stmt_summary_history_size = 24;

上述配置生效后,statements_summary 表每 30 分钟清空一次,statements_summary_history 表最多存储 3000 种 SQL 类型,每种类型保留最近 24 个周期的数据。statements_summary_evicted 表记录最近 24 个周期内被淘汰的 SQL 语句,且每 30 分钟更新一次。

设置合适的语句概要表大小

系统运行一段时间后(具体时间取决于系统负载),你可以通过查询 statement_summary 表判断是否发生了 SQL 淘汰。例如:

select @@global.tidb_stmt_summary_max_stmt_count; select count(*) from information_schema.statements_summary;
+-------------------------------------------+ | @@global.tidb_stmt_summary_max_stmt_count | +-------------------------------------------+ | 3000 | +-------------------------------------------+ 1 row in set (0.001 sec) +----------+ | count(*) | +----------+ | 3001 | +----------+ 1 row in set (0.001 sec)

可以看到 statements_summary 表已满。接着可以通过 statements_summary_evicted 表查看被淘汰的数据:

select * from information_schema.statements_summary_evicted;
+---------------------+---------------------+---------------+ | BEGIN_TIME | END_TIME | EVICTED_COUNT | +---------------------+---------------------+---------------+ | 2020-01-02 16:30:00 | 2020-01-02 17:00:00 | 59 | +---------------------+---------------------+---------------+ | 2020-01-02 16:00:00 | 2020-01-02 16:30:00 | 45 | +---------------------+---------------------+---------------+ 2 row in set (0.001 sec)

从上述结果可以看到,最多有 59 种 SQL 类型被淘汰。此时建议将 statement_summary 表的大小至少增加 59 条记录,即增大到至少 3059 条。

限制

默认情况下,语句概要表保存在内存中。当 TiDB 实例重启时,所有数据都会丢失。

持久化语句概要

本节仅适用于 TiDB 自建集群。对于 TiDB Cloud,tidb_stmt_summary_enable_persistent 参数的默认值为 false,且不支持动态修改。

限制 一节所述,语句概要表默认保存在内存中。一旦 TiDB 实例重启,所有语句概要数据都会丢失。从 v6.6.0 开始,TiDB 实验性地提供了配置项 tidb_stmt_summary_enable_persistent,允许用户开启或关闭语句概要持久化。

要开启语句概要持久化,可以在 TiDB 配置文件中添加如下配置项:

[instance] tidb_stmt_summary_enable_persistent = true # 以下为默认值,可根据需要修改。 # tidb_stmt_summary_filename = "tidb-statements.log" # tidb_stmt_summary_file_max_days = 3 # tidb_stmt_summary_file_max_size = 64 # MiB # tidb_stmt_summary_file_max_backups = 0

开启语句概要持久化后,内存中只保留当前实时数据,不再保留历史数据。每当实时数据被刷新为历史数据时,会按照 参数配置 中的 tidb_stmt_summary_refresh_interval 间隔写入磁盘。查询 statements_summary_historycluster_statements_summary_history 表时,会返回内存和磁盘上的数据合并结果。

排查示例

本节通过两个示例说明如何利用语句概要功能排查 SQL 性能问题。

SQL 延迟高是否由服务端引起?

本例中,客户端在对 employee 表进行点查时表现缓慢。你可以对 SQL 文本进行模糊查询:

SELECT avg_latency, exec_count, query_sample_text FROM information_schema.statements_summary WHERE digest_text LIKE 'select * from employee%';

1ms0.3msavg_latency 属于正常范围,因此可以判断服务端不是慢的原因。你可以继续排查客户端或网络问题。

+-------------+------------+------------------------------------------+ | avg_latency | exec_count | query_sample_text | +-------------+------------+------------------------------------------+ | 1042040 | 2 | select * from employee where name='eric' | | 345053 | 3 | select * from employee where id=3100 | +-------------+------------+------------------------------------------+ 2 rows in set (0.00 sec)

哪些类别的 SQL 语句总耗时最长?

如果 10:00 到 10:30 期间 QPS 明显下降,你可以从历史表中找出总耗时最长的三类 SQL 语句:

SELECT sum_latency, avg_latency, exec_count, query_sample_text FROM information_schema.statements_summary_history WHERE summary_begin_time='2020-01-02 10:00:00' ORDER BY sum_latency DESC LIMIT 3;

结果显示以下三类 SQL 语句总耗时最长,应优先优化。

+-------------+-------------+------------+-----------------------------------------------------------------------+ | sum_latency | avg_latency | exec_count | query_sample_text | +-------------+-------------+------------+-----------------------------------------------------------------------+ | 7855660 | 1122237 | 7 | select avg(salary) from employee where company_id=2013 | | 7241960 | 1448392 | 5 | select * from employee join company on employee.company_id=company.id | | 2084081 | 1042040 | 2 | select * from employee where name='eric' | +-------------+-------------+------------+-----------------------------------------------------------------------+ 3 rows in set (0.00 sec)

字段说明

statements_summary 字段说明

以下为 statements_summary 表中各字段的说明。

基础字段:

  • STMT_TYPE:SQL 语句类型。
  • SCHEMA_NAME:该类别 SQL 语句执行时的当前 schema。
  • DIGEST:该类别 SQL 语句的摘要。
  • DIGEST_TEXT:标准化后的 SQL 语句。
  • QUERY_SAMPLE_TEXT:该类别 SQL 语句的原始 SQL,仅取一条。
  • TABLE_NAMES:SQL 涉及的所有表,多个表用逗号分隔。
  • INDEX_NAMES:SQL 涉及的所有索引,多个索引用逗号分隔。
  • SAMPLE_USER:执行该类别 SQL 语句的用户,仅取一个。
  • PLAN_DIGEST:执行计划的摘要。
  • PLAN:原始执行计划,若有多条语句,仅取一条的计划。
  • BINARY_PLAN:二进制编码的原始执行计划,若有多条语句,仅取一条的计划。可通过 SELECT tidb_decode_binary_plan('xxx...') 解析具体执行计划。
  • PLAN_CACHE_HITS:该类别 SQL 命中执行计划缓存的总次数。
  • PLAN_IN_CACHE:上一次执行该类别 SQL 是否命中执行计划缓存。
  • PLAN_CACHE_UNQUALIFIED:该类别 SQL 未命中执行计划缓存的次数。
  • PLAN_CACHE_UNQUALIFIED_LAST_REASON:该类别 SQL 上一次未命中执行计划缓存的原因。

与执行时间相关的字段:

  • SUMMARY_BEGIN_TIME:当前统计周期的起始时间。
  • SUMMARY_END_TIME:当前统计周期的结束时间。
  • FIRST_SEEN:首次出现该类别 SQL 语句的时间。
  • LAST_SEEN:最后一次出现该类别 SQL 语句的时间。

与 TiDB 实例相关的字段:

  • EXEC_COUNT:该类别 SQL 语句的总执行次数。
  • SUM_ERRORS:执行过程中发生的错误总数。
  • SUM_WARNINGS:执行过程中发生的警告总数。
  • SUM_LATENCY:该类别 SQL 语句的总执行延迟。
  • MAX_LATENCY:该类别 SQL 语句的最大执行延迟。
  • MIN_LATENCY:该类别 SQL 语句的最小执行延迟。
  • AVG_LATENCY:该类别 SQL 语句的平均执行延迟。
  • AVG_PARSE_LATENCY:解析器的平均延迟。
  • MAX_PARSE_LATENCY:解析器的最大延迟。
  • AVG_COMPILE_LATENCY:编译器的平均延迟。
  • MAX_COMPILE_LATENCY:编译器的最大延迟。
  • AVG_MEM:平均使用内存(字节)。
  • MAX_MEM:最大使用内存(字节)。
  • AVG_DISK:平均使用磁盘空间(字节)。
  • MAX_DISK:最大使用磁盘空间(字节)。
  • AVG_TIDB_CPU_TIME:该类别 SQL 语句在 TiDB 实例上消耗的平均 CPU 时间。仅在开启 Top SQL 功能时有意义,否则值为 0

与 TiKV Coprocessor 任务相关的字段:

  • SUM_COP_TASK_NUM:发送的 Coprocessor 请求总数。
  • MAX_COP_PROCESS_TIME:Coprocessor 任务的最大执行时间。
  • MAX_COP_PROCESS_ADDRESS:执行时间最长的 Coprocessor 任务的地址。
  • MAX_COP_WAIT_TIME:Coprocessor 任务的最大等待时间。
  • MAX_COP_WAIT_ADDRESS:等待时间最长的 Coprocessor 任务的地址。
  • AVG_PROCESS_TIME:SQL 在 TiKV 的平均处理时间。
  • MAX_PROCESS_TIME:SQL 在 TiKV 的最大处理时间。
  • AVG_WAIT_TIME:SQL 在 TiKV 的平均等待时间。
  • MAX_WAIT_TIME:SQL 在 TiKV 的最大等待时间。
  • AVG_BACKOFF_TIME:SQL 遇到需重试错误时的平均等待时间。
  • MAX_BACKOFF_TIME:SQL 遇到需重试错误时的最大等待时间。
  • AVG_TOTAL_KEYS:Coprocessor 扫描的平均 key 数量。
  • MAX_TOTAL_KEYS:Coprocessor 扫描的最大 key 数量。
  • AVG_PROCESSED_KEYS:Coprocessor 处理的平均 key 数量。与 avg_total_keys 相比,avg_processed_keys 不包含 MVCC 的旧版本。如果两者差异较大,说明存在大量旧版本。
  • MAX_PROCESSED_KEYS:Coprocessor 处理的最大 key 数量。
  • AVG_TIKV_CPU_TIME:该类别 SQL 语句在 TiKV 实例上消耗的平均 CPU 时间。

与事务相关的字段:

  • AVG_PREWRITE_TIME:预写阶段的平均耗时。
  • MAX_PREWRITE_TIME:预写阶段的最大耗时。
  • AVG_COMMIT_TIME:提交阶段的平均耗时。
  • MAX_COMMIT_TIME:提交阶段的最大耗时。
  • AVG_GET_COMMIT_TS_TIME:获取 commit_ts 的平均耗时。
  • MAX_GET_COMMIT_TS_TIME:获取 commit_ts 的最大耗时。
  • AVG_COMMIT_BACKOFF_TIME:提交阶段遇到需重试错误时的平均等待时间。
  • MAX_COMMIT_BACKOFF_TIME:提交阶段遇到需重试错误时的最大等待时间。
  • AVG_RESOLVE_LOCK_TIME:事务间锁冲突的平均解决时间。
  • MAX_RESOLVE_LOCK_TIME:事务间锁冲突的最大解决时间。
  • AVG_LOCAL_LATCH_WAIT_TIME:本地事务的平均等待时间。
  • MAX_LOCAL_LATCH_WAIT_TIME:本地事务的最大等待时间。
  • AVG_WRITE_KEYS:平均写入 key 数量。
  • MAX_WRITE_KEYS:最大写入 key 数量。
  • AVG_WRITE_SIZE:平均写入数据量(字节)。
  • MAX_WRITE_SIZE:最大写入数据量(字节)。
  • AVG_PREWRITE_REGIONS:预写阶段涉及的 Region 平均数量。
  • MAX_PREWRITE_REGIONS:预写阶段涉及的最大 Region 数量。
  • AVG_TXN_RETRY:事务平均重试次数。
  • MAX_TXN_RETRY:事务最大重试次数。
  • SUM_BACKOFF_TIMES:该类别 SQL 语句遇到需重试错误的总重试次数。
  • BACKOFF_TYPES:所有需重试错误类型及各类型的重试次数。字段格式为 type:number,多个类型用逗号分隔,如 txnLock:2,pdRPC:1
  • AVG_AFFECTED_ROWS:平均影响行数。
  • PREV_SAMPLE_TEXT:当前 SQL 为 COMMIT 时,PREV_SAMPLE_TEXT 为上一个语句。此时,SQL 会按摘要和 prev_sample_text 分组,即不同 prev_sample_textCOMMIT 语句会分到不同行。当前 SQL 不是 COMMIT 时,PREV_SAMPLE_TEXT 为空字符串。

与资源管控相关的字段:

  • AVG_REQUEST_UNIT_WRITE:SQL 平均消耗的写 RU 数量。
  • MAX_REQUEST_UNIT_WRITE:SQL 最大消耗的写 RU 数量。
  • AVG_REQUEST_UNIT_READ:SQL 平均消耗的读 RU 数量。
  • MAX_REQUEST_UNIT_READ:SQL 最大消耗的读 RU 数量。
  • AVG_QUEUED_RC_TIME:SQL 等待可用 RU 的平均时间。
  • MAX_QUEUED_RC_TIME:SQL 等待可用 RU 的最大时间。
  • RESOURCE_GROUP:SQL 绑定的资源组。

statements_summary_evicted 字段说明

  • BEGIN_TIME:记录起始时间。
  • END_TIME:记录结束时间。
  • EVICTED_COUNT:该周期内被淘汰的 SQL 类型数量。

文档内容是否有帮助?