MySQL 伺服器能夠維護陳述式摘要資訊。摘要處理會將每個 SQL 陳述式轉換為正規化形式(陳述式摘要),並從正規化結果計算 SHA-256 雜湊值(摘要雜湊值)。正規化允許將類似的陳述式分組和摘要,以公開伺服器正在執行的陳述式類型以及它們發生的頻率。對於每個摘要,會儲存產生摘要的代表性陳述式作為範例。本節說明如何進行陳述式摘要和取樣,以及它們如何有用。
無論 Performance Schema 是否可用,摘要處理都會在剖析器中發生,以便其他功能(例如 MySQL Enterprise Firewall 和查詢重寫外掛程式)可以存取陳述式摘要。
當剖析器收到 SQL 陳述式時,如果需要摘要,它會計算陳述式摘要,以下任何條件為 true 時,即為需要摘要
已啟用 Performance Schema 摘要檢測
已啟用 MySQL Enterprise Firewall
已啟用查詢重寫外掛程式
剖析器也由 STATEMENT_DIGEST_TEXT()
和 STATEMENT_DIGEST()
函數使用,應用程式可以呼叫這些函數,分別從 SQL 陳述式計算正規化陳述式摘要和摘要雜湊值。
max_digest_length
系統變數值決定每個工作階段可用於計算正規化陳述式摘要的最大位元組數。在摘要計算期間使用該空間量後,會發生截斷:不會收集剖析陳述式的其他符號,也不會計入其摘要值。僅在已剖析符號的許多位元組後不同的陳述式會產生相同的正規化陳述式摘要,並且如果進行比較或為摘要統計資料彙總,則會被視為相同。
將 max_digest_length
系統變數設定為零會停用摘要產生,這也會停用需要摘要的伺服器功能。
在計算正規化陳述式後,會從它計算 SHA-256 雜湊值。此外
如果已啟用 MySQL Enterprise Firewall,則會呼叫它,並且會向其提供計算的摘要。
如果已啟用任何查詢重寫外掛程式,則會呼叫它,並且會向其提供陳述式摘要和摘要值。
如果 Performance Schema 已啟用摘要檢測,則會複製正規化陳述式摘要,為其配置最多
performance_schema_max_digest_length
個位元組。因此,如果performance_schema_max_digest_length
小於max_digest_length
,則相對於原始值,副本會被截斷。正規化陳述式摘要的副本會儲存在適當的 Performance Schema 資料表中,以及從原始正規化陳述式計算的 SHA-256 雜湊值。(如果 Performance Schema 相對於原始值截斷其正規化陳述式摘要副本,則不會重新計算 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
消費者控制效能架構是否維護摘要資訊。請參閱陳述式摘要消費者。陳述式事件表格(
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 的語句事件表可能會儲存許多摘要,將 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 |
+----------------------------------------------------------------------+
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。