MySQL 伺服器能夠維護語句摘要資訊。摘要程序會將每個 SQL 陳述式轉換為標準化形式(語句摘要),並從標準化結果計算 SHA-256 雜湊值(摘要雜湊值)。標準化允許將相似的陳述式分組並摘要,以公開關於伺服器正在執行的陳述式類型以及它們發生的頻率的資訊。對於每個摘要,會儲存產生摘要的代表性陳述式作為範例。本節說明語句摘要和取樣是如何發生的,以及它們如何有用。
摘要發生在剖析器中,無論 Performance Schema 是否可用,因此其他功能(例如 MySQL Enterprise Firewall 和查詢重寫外掛程式)都可以存取語句摘要。
當剖析器收到 SQL 陳述式時,如果需要摘要,它會計算語句摘要,如果符合下列任何條件,則為真:
已啟用 Performance Schema 摘要檢測
已啟用 MySQL Enterprise Firewall
已啟用查詢重寫外掛程式
剖析器也由 STATEMENT_DIGEST_TEXT()
和 STATEMENT_DIGEST()
函數使用,應用程式可以呼叫這些函數,分別從 SQL 陳述式計算標準化語句摘要和摘要雜湊值。
max_digest_length
系統變數值決定每個工作階段可用於計算標準化語句摘要的最大位元組數。一旦在摘要計算期間使用該空間量,就會發生截斷:不會再從剖析的陳述式收集進一步的權杖,也不會計入其摘要值。僅在剖析的權杖的那些位元組之後不同的陳述式會產生相同的標準化語句摘要,並且如果在比較或為摘要統計彙總時,會被視為相同。
將 max_digest_length
系統變數設定為零會停用摘要產生,這也會停用需要摘要的伺服器功能。
在計算出標準化陳述式後,會從中計算 SHA-256 雜湊值。此外
如果啟用 MySQL Enterprise Firewall,則會呼叫它,並且可使用計算出的摘要。
如果啟用任何查詢重寫外掛程式,則會呼叫它,並且可使用語句摘要和摘要值。
如果效能架構 (Performance Schema) 啟用了摘要 (digest) 工具,它會複製標準化的陳述式摘要,並為其配置最多
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 ...
在這種情況下,第二個欄位名稱的差異會遺失,並且兩個陳述式都被視為相同。
在效能架構中,陳述式摘要包含以下元素
在
setup_consumers
表格中的statements_digest
消費者 (consumer) 控制效能架構是否維護摘要資訊。請參閱陳述式摘要消費者。陳述式事件表格 (
events_statements_current
、events_statements_history
和events_statements_history_long
) 具有用於儲存標準化陳述式摘要和對應摘要 SHA-256 雜湊值的欄位。DIGEST_TEXT
是標準化陳述式摘要的文字。這是原始標準化陳述式的副本,計算到最大max_digest_length
位元組,並根據需要進一步截斷到performance_schema_max_digest_length
位元組。DIGEST
是從原始標準化陳述式計算出的摘要 SHA-256 雜湊值。
events_statements_summary_by_digest
摘要表格提供彙總的陳述式摘要資訊。此表格彙總每個SCHEMA_NAME
和DIGEST
組合的陳述式資訊。效能架構使用 SHA-256 雜湊值進行彙總,因為它們計算速度快,並且具有有利的統計分佈,可最大程度地減少衝突。請參閱第 29.12.20.3 節,「陳述式摘要表格」。
某些效能表格具有一個欄位,用於儲存計算摘要的原始 SQL 陳述式。
events_statements_current
、events_statements_history
和events_statements_history_long
陳述式事件表格的SQL_TEXT
欄位。events_statements_summary_by_digest
摘要表格的QUERY_SAMPLE_TEXT
欄位。
預設情況下,陳述式顯示的最大可用空間為 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
位元組的標準化陳述式摘要。效能架構不會進一步截斷它儲存的標準化陳述式摘要,而是為每個摘要配置比
max_digest_length
位元組更多的記憶體,這是不必要的。
如果
max_digest_length
等於performance_schema_max_digest_length
效能架構以外的伺服器功能會使用最多佔用
max_digest_length
位元組的標準化陳述式摘要。效能架構不會進一步截斷它儲存的標準化陳述式摘要,並且為每個摘要配置與
max_digest_length
位元組相同的記憶體量。
如果
max_digest_length
大於performance_schema_max_digest_length
效能架構以外的伺服器功能會使用最多佔用
max_digest_length
位元組的標準化陳述式摘要。效能架構會進一步截斷它儲存的標準化陳述式摘要,並且為每個摘要配置比
max_digest_length
位元組更少的記憶體。
由於效能架構陳述式事件表格可能儲存許多摘要,因此將 performance_schema_max_digest_length
設定為小於 max_digest_length
,可以讓管理員平衡以下因素
伺服器功能需要提供可用的長標準化陳述式摘要 (效能架構以外)
許多並行工作階段,每個工作階段都會配置摘要計算記憶體
需要在儲存許多陳述式摘要時限制效能架構陳述式事件表格的記憶體消耗
設定 performance_schema_max_digest_length
並非針對每個連線 (session),而是針對每個陳述式 (statement)。一個連線可以在 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
陳述式,或監控這些儀器 (instruments)。
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 |
+----------------------------------------------------------------------+
Performance Schema 使用陳述式取樣來收集產生 events_statements_summary_by_digest
表格中每個摘要值的代表性陳述式。這些欄位儲存取樣陳述式資訊:QUERY_SAMPLE_TEXT
(陳述式文字)、QUERY_SAMPLE_SEEN
(陳述式被看到的時間)和 QUERY_SAMPLE_TIMER_WAIT
(陳述式等待或執行時間)。Performance Schema 會在每次選擇取樣陳述式時更新這三個欄位。
當插入新的表格列時,產生列摘要值的陳述式會儲存為與摘要相關聯的目前取樣陳述式。此後,當伺服器看到具有相同摘要值的其他陳述式時,它會判斷是否使用新的陳述式來取代目前的取樣陳述式(也就是是否重新取樣)。重新取樣策略基於目前的取樣陳述式和新陳述式的相對等待時間,以及選擇性的目前取樣陳述式的存在時間。
基於等待時間的重新取樣:如果新陳述式的等待時間大於目前取樣陳述式的等待時間,則它會成為目前的取樣陳述式。
基於存在時間的重新取樣:如果
performance_schema_max_digest_sample_age
系統變數的值大於零,且目前取樣陳述式的存在時間超過這個秒數,則會認為目前的陳述式「太舊」,而新陳述式會取代它。即使新陳述式的等待時間小於目前取樣陳述式的等待時間,也會發生這種情況。
預設情況下,performance_schema_max_digest_sample_age
為 60 秒(1 分鐘)。若要變更取樣陳述式因存在時間而「過期」的速度,請增加或減少該值。若要停用基於存在時間的重新取樣策略部分,請將 performance_schema_max_digest_sample_age
設定為 0。