MySQL 服务器能够维护语句摘要信息。摘要过程将每个 SQL 语句转换为规范化形式(语句摘要),并根据规范化结果计算 MD5 哈希值(摘要哈希值)。规范化允许对相似的语句进行分组和汇总,以公开有关服务器正在执行的语句类型及其发生频率的信息。本节描述语句摘要是如何发生的以及它如何有用。
无论 Performance Schema 是否可用,都会在解析器中进行摘要,以便其他服务器组件(例如 MySQL Enterprise Firewall 和查询重写插件)可以访问语句摘要。
当解析器收到 SQL 语句时,如果需要该摘要,它会计算一个语句摘要,如果以下任何条件为真,则为真:
性能模式摘要检测已启用
MySQL 企业防火墙已启用
查询重写插件已启用
max_digest_length
系统变量值确定每个会话可用于计算规范化语句摘要的最大字节数
。一旦在摘要计算期间使用了该数量的空间,就会发生截断:不再收集来自已解析语句的标记或将其计入其摘要值。仅在许多字节的已解析令牌产生相同的规范化语句摘要之后才不同的语句,如果进行比较或汇总以获取摘要统计信息,则这些语句被认为是相同的。
将max_digest_length
系统变量设置为零会禁用摘要生成,这也会禁用需要摘要的服务器功能。
在计算出规范化语句后,从中计算出一个 MD5 散列值。此外:
如果启用了 MySQL Enterprise Firewall,它会被调用并且计算出的摘要对它可用。
如果启用了任何查询重写插件,则会调用它并且语句摘要和摘要值可供它使用。
如果 Performance Schema 启用了摘要检测,它会制作规范化语句摘要的副本,为其分配最大
performance_schema_max_digest_length
字节数。因此,如果performance_schema_max_digest_length
小于max_digest_length
,则副本相对于原件被截断。规范化语句摘要的副本连同根据原始规范化语句计算的 MD5 哈希值存储在适当的性能模式表中。(如果 Performance Schema 截断了其相对于原始语句摘要的规范化语句摘要副本,则它不会重新计算 MD5 哈希值。)
语句规范化将语句文本转换为更标准化的摘要字符串表示形式,该表示形式保留了一般语句结构,同时删除了对该结构不重要的信息:
保留对象标识符,例如数据库和表名称。
文字值被转换为参数标记。规范化语句不保留名称、密码、日期等信息。
删除注释并调整空格。
考虑这些陈述:
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 ...
在这种情况下,第二列名称中的差异将丢失,并且两个语句被认为是相同的。
在 Performance Schema 中,语句摘要涉及这些元素:
表中的
statements_digest
消费者setup_consumers
控制性能模式是否维护摘要信息。请参阅 声明摘要消费者。语句事件表(
events_statements_current
、events_statements_history
和events_statements_history_long
)具有用于存储规范化语句摘要和相应摘要 MD5 哈希值的列:DIGEST_TEXT
是规范化语句摘要的文本。这是原始规范化语句的副本,已计算为最大max_digest_length
字节数,必要时进一步截断为performance_schema_max_digest_length
字节数。DIGEST
是从原始规范化语句计算的摘要 MD5 哈希值。
摘要
events_statements_summary_by_digest
表提供聚合的语句摘要信息。此表汇总了每个语句SCHEMA_NAME
和DIGEST
组合的信息。Performance Schema 使用 MD5 哈希值进行聚合,因为它们计算速度快,并且具有有利的统计分布,可以最大限度地减少冲突。请参阅 第 25.12.15.3 节,“语句汇总表”。
语句事件表还有一
SQL_TEXT
列包含原始 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_NAME
和DIGEST
值与表中现有值不匹配的语句分组在特殊行中SCHEMA_NAME
并
DIGEST
设置为NULL
。这允许计算所有语句。但是,如果特殊行占执行语句的很大百分比,则可能需要通过增加 来增加摘要表的大小
performance_schema_digests_size
。
对于生成仅在末尾不同的非常长的语句的应用程序,增加
max_digest_length
可以计算摘要以区分否则会聚合到同一摘要的语句。相反,减少
max_digest_length
会导致服务器将更少的内存用于摘要存储,但会增加较长语句聚合到同一摘要的可能性。管理员应该记住,较大的值会导致相应增加的内存需求,特别是对于涉及大量同时会话的工作负载(服务器
max_digest_length
为每个会话分配字节)。
如前所述,由解析器计算的规范化语句摘要被限制为最大
max_digest_length
字节数,而存储在性能模式中的规范化语句摘要使用
performance_schema_max_digest_length
字节。以下内存使用注意事项适用于
max_digest_length
和
的相对值performance_schema_max_digest_length
:
如果
max_digest_length
小于performance_schema_max_digest_length
:性能模式以外的服务器组件使用最多
max_digest_length
字节的规范化语句摘要。Performance Schema 不会进一步截断它存储的规范化语句摘要,而是
max_digest_length
为每个摘要分配比字节数更多的内存,这是不必要的。
如果
max_digest_length
等于performance_schema_max_digest_length
:性能模式以外的服务器组件使用最多
max_digest_length
字节的规范化语句摘要。Performance Schema 不会进一步截断它存储的规范化语句摘要,并分配与
max_digest_length
每个摘要字节数相同的内存量。
如果
max_digest_length
大于performance_schema_max_digest_length
:性能模式以外的服务器组件使用最多
max_digest_length
字节的规范化语句摘要。Performance Schema 进一步截断它存储的规范化语句摘要,并分配比
max_digest_length
每个摘要字节数更少的内存。
因为 Performance Schema 语句事件表可能存储许多摘要,所以设置
performance_schema_max_digest_length
小于max_digest_length
使管理员能够平衡这些因素:
需要为 Performance Schema 之外的服务器组件提供长的规范化语句摘要
许多并发会话,每个会话分配摘要计算内存
在存储许多语句摘要时需要限制 Performance Schema 语句事件表的内存消耗
该
performance_schema_max_digest_length
设置不是每个会话,它是每个语句,一个会话可以在
events_statements_history
表中存储多个语句。此表中的典型语句数是每个会话 10 个,因此每个会话
performance_schema_max_digest_length
仅针对此表消耗 10 倍的值所指示的内存。
此外,在全球范围内收集了许多声明(和摘要),最显着的是在
events_statements_history_long
表中。在这里,N
存储的语句也消耗了值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 |
+----------------------------------------------------------------------+