25.10 性能架构语句摘要

MySQL 服务器能够维护语句摘要信息。摘要处理将每个 SQL 语句转换为规范化形式(语句摘要),并根据规范化结果计算 MD5 哈希值(摘要哈希值)。规范化允许对相似的语句进行分组和汇总,以公开有关服务器正在执行的语句类型及其发生频率的信息。本节描述语句摘要的发生方式及其用法。

无论性能模式是否可用,解析器都会进行摘要,因此其他服务器组件(例如 MySQL Enterprise Firewall 和查询重写插件)可以访问语句摘要。

声明摘要的一般概念

当解析器收到一条 SQL 语句时,如果需要该摘要,它将计算一条语句摘要,如果满足以下任一条件,则为 true:

  • 启用性能架构摘要检测

  • MySQL 企业防火墙已启用

  • 查询重写插件已启用

max_digest_length系统变量值确定每个会话可用于计算标准化语句摘要的最大字节数。一旦在摘要计算中使用了一定数量的空间,就会发生截断:不再收集来自已解析语句的其他标记或将其计入其摘要值。只有在解析的令牌的多个字节产生相同的规范化语句摘要之后才不同的语句,如果比较或汇总摘要统计信息,这些语句将被视为相同。

在计算完标准化的语句后,将根据该语句计算 MD5 哈希值。此外:

  • 如果启用了 MySQL 企业防火墙,则会调用它,并且可以使用计算出的摘要。

  • 如果启用了任何“查询重写插件”,则将调用它,并且语句摘要和摘要值可供使用。

  • 如果性能模式启用了摘要检测,它将复制规范化语句摘要,并为其分配最多performance_schema_max_digest_length个字节。因此,如果performance_schema_max_digest_length小于max_digest_length,则副本相对于原始副本将被截断。规范化语句摘要的副本与从原始规范化语句计算出的 MD5 哈希值一起存储在适当的 Performance Schematable 中。 (如果性能架构相对于原始版本截断了其规范化语句摘要的副本,则它不会重新计算 MD5 哈希值.)

语句规范化将语句文本转换为更标准化的摘要字符串 table 示形式,该 table 示形式保留了常规语句结构,同时删除了对该结构不重要的信息:

  • 保留对象标识符,例如数据库和 table 名。

  • Literals 值将转换为参数标记。规范化的语句不保留诸如名称,密码,日期等信息。

  • 删除 Comments 并调整空白。

考虑以下语句:

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 > ?

规范化的语句包含的信息较少,但仍代 table 原始语句。具有不同数据值的其他类似语句具有相同的规范化形式。

现在考虑以下语句:

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 ...

在这种情况下,第二列名称中的差异将丢失,并且两个语句都被视为相同。

性能模式中的语句摘要

在性能模式中,语句摘要涉及以下组件:

See 第 25.12.6 节“性能架构语句事件 table”.

语句事件 table 还具有一个SQL_TEXT列,其中包含原始 SQL 语句。默认情况下,可用于语句显示的最大空间为 1024 字节。要更改此值,请在服务器启动时设置performance_schema_max_sql_text_length系统变量。

performance_schema_max_digest_length系统变量确定每个语句可用于性能模式中摘要值存储的最大字节数。但是,由于诸如关键字和 Literals 值之类的语句组件的内部编码,语句摘要的显示长度可能比可用缓冲区长。因此,从语句事件 table 的DIGEST_TEXT列中选择的值可能看起来超过performance_schema_max_digest_length值。

events_statements_summary_by_digest摘要 table 提供了服务器执行的语句的概要文件。它显示了应用程序执行哪种类型的语句以及执行频率。应用程序开发人员可以将此信息与 table 中的其他信息一起使用,以评估应用程序的性能 Feature。例如,显示 await 时间,锁定时间或索引使用的 table 列可能会突出显示效率低下的查询类型。这使开发人员可以洞悉需要注意应用程序的哪些部分。

events_statements_summary_by_digest摘要 table 的大小固定。默认情况下,性能架构会估计要在启动时使用的大小。要显式指定 table 大小,请在服务器启动时设置performance_schema_digests_size系统变量。如果 table 已满,则性能模式会将具有SCHEMA_NAMEDIGEST值与 table 中现有值不匹配的语句分组在SCHEMA_NAMEDIGEST设置为NULL的特殊行中。这样可以计算所有语句。但是,如果特殊行占执行语句的很大一部分,则可能希望通过增加performance_schema_digests_size来增加摘要 table 的大小。

语句摘要存储器的使用

对于生成仅在结尾处不同的非常长的语句的应用程序,增加max_digest_length将启用摘要的计算,这些摘要可区分会聚合到同一摘要的语句。相反,减小max_digest_length会导致服务器将较少的内存用于摘要存储,但是会增加将较长的语句聚合到同一摘要的可能性。Management 员应记住,较大的值会相应增加内存需求,特别是对于涉及大量同时会话的工作负载(服务器为每个会话分配max_digest_length个字节)。

如前所述,解析器计算的规范化语句摘要被限制为最大max_digest_length个字节,而存储在性能模式中的规范化语句摘要则使用performance_schema_max_digest_length个字节。以下是有关max_digest_lengthperformance_schema_max_digest_length相对值的内存使用注意事项:

由于 Performance Schema 语句事件 table 可能存储许多摘要,因此将performance_schema_max_digest_length设置为小于max_digest_length可使 Management 员平衡以下因素:

  • 对于性能模式外部的服务器组件,需要具有较长的规范化语句摘要

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

  • 存储许多语句摘要时,需要通过 Performance Schema 语句事件 table 来限制内存消耗

performance_schema_max_digest_length设置不是针对每个会话,而是针对每个语句,并且一个会话可以在events_statements_historytable 中存储多个语句。该 table 中的典型语句数是每个会话 10 条,因此,仅对于此 table,每个会话将消耗performance_schema_max_digest_length值指示的内存的 10 倍。

另外,全局(尤其是在events_statements_history_longtable 中)收集了很多语句(和摘要)。同样,这里存储的* N *语句将消耗_N *乘以performance_schema_max_digest_length值指示的内存。

要评估用于 SQL 语句存储和摘要计算的内存量,请使用显示引擎 PERFORMANCE_SCHEMA 状态语句,或监视以下工具:

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      |
+----------------------------------------------------------------------+