Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  MySQL Performance Schema  /  Performance Schema Statement Digests and Sampling

29.10 性能模式语句摘要和采样

MySQL服务器能够维护语句摘要信息。摘要过程将每个SQL语句转换为标准化形式(即语句摘要)并从标准化结果中计算一个SHA-256哈希值(即摘要哈希值)。标准化允许将类似的语句进行分组和总结,以揭示服务器正在执行的语句类型及其频率。对于每个摘要,代表该摘要的语句作为样本被存储。这一节描述了如何在性能模式中实现语句摘要和采样,以及它们是如何有用的。

摘要过程在不考虑性能模式是否可用时由解析器执行,因此其他功能,如MySQL Enterprise Firewall和查询重写插件,可以访问语句摘要。

当解析器接收一个SQL语句时,它会计算一个语句摘要,如果需要的话,这通常是因为以下任何条件为真:

  • 性能模式的摘要指令化已启用

  • MySQL Enterprise Firewall已启用

  • 有查询重写插件已启用

解析器还用于STATEMENT_DIGEST_TEXT()STATEMENT_DIGEST()函数,这些函数允许应用程序计算一个SQL语句的标准化摘要和一个摘要哈希值。应用程序可以调用这些函数来从SQL语句中计算标准化摘要和摘要哈希值。

max_ digest_length系统变量的值确定每个会话可用于计算标准化语句摘要的最大字节数。一旦在摘要计算过程中使用了该数量的字节,截断发生:不会收集或考虑解析后的任何其他令牌。产生相同标准化语句摘要的语句,只要它们在那个数量的字节内不同,将被认为是相同的,如果进行比较或聚合以用于摘要统计。

Warning

max_ digest_length系统变量设置为零会禁用摘要生产,这也会禁用需要摘要的服务器功能。

在计算标准化语句后,会从中计算一个SHA-256哈希值。此外:

  • 如果MySQL Enterprise Firewall已启用,它将被调用,并且可用于它的摘要。

  • 如果有任何查询重写插件已启用,它们将被调用,语句摘要和摘要哈希值将被提供给它们。

  • 如果性能模式的摘要指令化已启用,它会复制标准化的语句摘要,将其分配一个最大长度为performance_ schema_ max_ digest_length字节。因此,如果performance_ schema_ max_ digest_length小于max_ digest_length,复制的标准化语句摘要将相对于原始值进行截断。复制的标准化语句摘要在性能模式表中存储,包括从原始标准化语句计算出的SHA-256哈希值。 (如果性能模式对其复制的标准化语句摘要进行了截断,它不会重新计算SHA-256哈希值。)

语句标准化将语句文本转换为一个更标准化的摘要字符串表示形式,该表示形式保留了一般语句结构,同时去除了不必要的信息:

  • 对象标识符,如数据库和表名,保持不变。

  • 文字值被替换为参数占位符。标准化后的语句不保存任何信息,如名称、密码、日期等。

  • 注释被移除,并调整了空格。

考虑这些语句:

SELECT * FROM orders WHERE customer_id=10 AND quantity>20
SELECT * FROM orders WHERE customer_id = 20 AND quantity > 100

为了标准化这些语句,解析器将数据值替换为?并调整空格。两个语句产生相同的标准化形式,因此被认为是“相同”的:

SELECT * FROM orders WHERE customer_id = ? AND quantity > ?

归一化后的声明包含了更少的信息,但仍然代表了原始声明。具有不同数据值但结构相似的其他声明有相同的归一化形式。

现在考虑这些声明:

SELECT * FROM customers WHERE customer_id = 1000
SELECT * FROM orders WHERE customer_id = 1000

在这种情况下,归一化后的声明因为对象标识符不同而有所差异:

SELECT * FROM customers WHERE customer_id = ?
SELECT * FROM orders WHERE customer_id = ?

如果归一化产生的声明超过了摘要缓冲区可用的空间(由max_digest_length确定),则截断发生,并且文本以...结束。只在...之后的部分不同,归一化后的声明被认为相同。考虑这些声明:

SELECT * FROM mytable WHERE cola = 10 AND colb = 20
SELECT * FROM mytable WHERE cola = 10 AND colc = 20

如果截断恰好发生在AND之后,两个声明都有这个归一化形式:

SELECT * FROM mytable WHERE cola = ? AND ...

在这种情况下,第二列名的差异丢失了,两个声明被认为是相同的。

在性能_schema中,语句摘要涉及这些元素:

一些性能表格有列用于存储原始SQL声明,这些声明用于计算摘要:

默认情况下,语句显示的最大空间为1024字节。要更改此值,请在服务器启动时设置performance_schema_max_sql_text_length系统变量。变化将影响所有前面命名的列所需的存储空间。

性能架构中的performance_schema_max_digest_length系统变量确定了每个语句可用于存储摘要值的最大字节数。在性能架构中,语句摘要可能会因为内部编码方式(如关键词和文字值)而显示为比可用缓冲区大小更长。因此,从DIGEST_TEXT列中获取的语句事件表中的摘要可能会超过performance_schema_max_digest_length值。

性能架构中的events_statements_summary_by_digest摘要表提供了服务器执行的语句概况。它显示了应用程序正在执行哪些类型的语句以及频率。开发者可以使用这个信息,结合其他表中的信息来评估应用程序的性能特征。例如,显示等待时间、锁定时间或索引使用情况的表列可能会突出那些效率低下的查询。这为开发者提供了了解哪些应用部分需要关注的线索。

性能架构中的events_statements_summary_by_digest摘要表有一个固定的大小。默认情况下,性能架构在启动时估算了使用的表大小。如果需要显式指定表大小,可以在服务器启动时设置performance_schema_digests_size系统变量。若摘要表满了,性能架构会将没有匹配现有值的SCHEMA_NAMEDIGEST的语句分组到一个特殊行中,SCHEMA_NAMEDIGEST都设置为NULL。这样所有的语句都可以被计数。但是,如果特殊行占据了执行的语句中很大比例,那么可能需要通过增加performance_schema_digests_size来增大摘要表大小。

对于生成非常长的语句并且只在末尾有所不同的事务应用程序,增加max_digest_length可以使得摘要计算出能够区分那些将会聚合到相同摘要的语句。相反,减少max_digest_length则导致服务器在存储摘要时使用更少的内存,但增加了长语句聚合到相同摘要的可能性。管理员应该记住,较大的值会对内存需求产生相应的影响,尤其是对于并发会话密集型工作负载(服务器为每个会话分配max_digest_length字节)。

如前所述,由解析器计算的标准化语句摘要被限制在max_digest_length字节内,而性能架构存储的标准化语句摘要使用performance_schema_max_digest_length字节。以下是关于max_digest_lengthperformance_schema_max_digest_length的内存使用考虑因素:

由于性能模式语句事件表可能存储许多摘要,设置performance_schema_max_ digest_length小于max_ digest_length可以帮助管理员平衡这些因素:

  • 需要对服务器外部特性可用的长标准化语句摘要

  • 许多并发会话,每个会话都分配摘要计算所需的内存

  • 限制性能模式语句事件表存储大量摘要时的内存消耗

设置performance_schema_max_ digest_length不是按会话进行的,它是每个语句的,一个会话可以在events_statements_history表中存储多个语句。一个典型的会话在这个表中有10个语句,因此每个会话为此表消耗的内存是performance_schema_max_ digest_length值的10倍,仅限于这个表。

此外,还有许多语句(和摘要)被全局收集,最著名的是events_statements_history_long表。这里,N个语句存储消耗了performance_schema_max_ digest_length值的内存。

要评估用于SQL语句存储和摘要计算所需的内存,请使用SHOW ENGINE PERFORMANCE_ SCHEMA STATUS语句,或者监控这些指标:

mysql> SELECT NAME
       FROM performance_schema.setup_instruments
       WHERE NAME LIKE '%.sqltext';
+------------------------------------------------------------------+
| NAME                                                             |
+------------------------------------------------------------------+
| memory/performance_schema/events_statements_history.sqltext      |
| memory/performance_schema/events_statements_current.sqltext      |
| memory/performance_schema/events_statements_history_long.sqltext |
+------------------------------------------------------------------+

mysql> SELECT NAME
       FROM performance_schema.setup_instruments
       WHERE NAME LIKE 'memory/performance_schema/%.tokens';
+----------------------------------------------------------------------+
| NAME                                                                 |
+----------------------------------------------------------------------+
| memory/performance_schema/events_statements_history.tokens           |
| memory/performance_schema/events_statements_current.tokens           |
| memory/performance_schema/events_statements_summary_by_digest.tokens |
| memory/performance_schema/events_statements_history_long.tokens      |
+----------------------------------------------------------------------+

性能模式使用语句采样来收集代表每个摘要值在events_statements_summary_by_digest表中的语句。这些列存储样本语句信息:QUERY_SAMPLE_TEXT(语句的文本),QUERY_SAMPLE_SEEN(当语句被看到时)和QUERY_SAMPLE_TIMER_WAIT(语句等待或执行时间)。性能模式每次选择样本语句时都会更新这三个列。

当插入新表行时,将产生该行摘要值的语句存储为当前与该摘要关联的样本语句。随后,当服务器看到其他具有相同摘要值的语句时,它会确定是否使用新的语句替换当前样本语句(即是否重新采样)。重新采样的政策基于当前样本语句和新语句相对等待时间以及,若可用,还基于当前样本语句的年龄:

  • 基于等待时间的重新采样:如果新语句的等待时间大于当前样本语句的等待时间,它将成为当前样本语句。

  • 基于年龄的重采样:如果系统变量performance_schema_max_digest_sample_age的值大于零,并且当前的样本语句超过了该值秒数,那么当前的语句被认为是“过时的”,并由新的语句替换。即使新语句的等待时间少于当前样本语句,也会发生这种情况。

默认情况下,performance_schema_max_digest_sample_age设置为60秒(1分钟)。要改变样本语句由于年龄“过期”的速度,可以增加或减少该值。要禁用基于年龄的重采样策略的一部分,设置performance_schema_max_digest_sample_age为0。