ANALYZE [NO_WRITE_TO_BINLOG | LOCAL]
TABLE tbl_name [, tbl_name] ...
ANALYZE [NO_WRITE_TO_BINLOG | LOCAL]
TABLE tbl_name
UPDATE HISTOGRAM ON col_name [, col_name] ...
[WITH N BUCKETS]
[{MANUAL | AUTO} UPDATE]
ANALYZE [NO_WRITE_TO_BINLOG | LOCAL]
TABLE tbl_name
UPDATE HISTOGRAM ON col_name [USING DATA 'json_data']
ANALYZE [NO_WRITE_TO_BINLOG | LOCAL]
TABLE tbl_name
DROP HISTOGRAM ON col_name [, col_name] ...
ANALYZE TABLE
產生表格統計資訊
ANALYZE TABLE
在沒有任何HISTOGRAM
子句的情況下,會執行索引鍵分佈分析,並儲存指定表格的分佈。對於MyISAM
表格,用於索引鍵分佈分析的ANALYZE TABLE
相當於使用 myisamchk --analyze。ANALYZE TABLE
使用UPDATE HISTOGRAM
子句會為指定的表格欄位產生直方圖統計資訊,並將它們儲存在資料字典中。此語法僅允許使用一個表格名稱。MySQL 也支援將單一欄位的直方圖設定為使用者定義的 JSON 值。ANALYZE TABLE
使用DROP HISTOGRAM
子句會從資料字典中移除指定表格欄位的直方圖統計資訊。此語法僅允許使用一個表格名稱。
ANALYZE TABLE
可用於 InnoDB
、NDB
和 MyISAM
表格。它不適用於檢視表。
如果啟用了 innodb_read_only
系統變數,則 ANALYZE TABLE
可能會失敗,因為它無法更新資料字典中使用的 InnoDB
統計表格。對於更新索引鍵分佈的 ANALYZE TABLE
操作,即使該操作更新的是表格本身(例如,如果是 MyISAM
表格),也可能會發生失敗。要取得更新後的分佈統計資訊,請設定 information_schema_stats_expiry=0
。
ANALYZE TABLE
支援分割表格,您可以使用 ALTER TABLE ... ANALYZE PARTITION
來分析一個或多個分割區;如需更多資訊,請參閱 第 15.1.9 節,「ALTER TABLE 陳述式」和 第 26.3.4 節,「分割區的維護」。
在分析期間,表格會以讀取鎖定鎖定 InnoDB
和 MyISAM
。
預設情況下,伺服器會將 ANALYZE TABLE
陳述式寫入二進位日誌,以便它們複製到複本。若要禁止記錄,請指定選用的 NO_WRITE_TO_BINLOG
關鍵字或其別名 LOCAL
。
ANALYZE TABLE
會傳回一個結果集,其中包含下表中顯示的欄位。
欄位 | 值 |
---|---|
表格 |
表格名稱 |
Op |
analyze 或 histogram |
Msg_type |
status 、error 、info 、note 或 warning |
Msg_text |
一則資訊訊息 |
沒有任何 HISTOGRAM
子句的 ANALYZE TABLE
會執行索引鍵分佈分析,並儲存表格的分佈。任何現有的直方圖統計資訊都保持不受影響。
如果表格自上次索引鍵分佈分析以來沒有變更,則不會再次分析該表格。
MySQL 使用儲存的索引鍵分佈來決定在非常數的聯結中,應該聯結表格的順序。此外,在決定查詢中特定表格使用哪個索引時,可以使用索引鍵分佈。
要檢查儲存的索引鍵分佈基數,請使用 SHOW INDEX
陳述式或 INFORMATION_SCHEMA
STATISTICS
表格。請參閱 第 15.7.7.23 節,「SHOW INDEX 陳述式」和 第 28.3.34 節,「INFORMATION_SCHEMA STATISTICS 表格」。
對於 InnoDB
表格,ANALYZE TABLE
會透過在每個索引樹上執行隨機深入檢查,並相應地更新索引基數估計值,來確定索引基數。由於這些只是估計值,因此重複執行 ANALYZE TABLE
可能會產生不同的數字。這使得 ANALYZE TABLE
在 InnoDB
表格上快速執行,但不是 100% 精確,因為它不會將所有列都納入考量。
您可以啟用 innodb_stats_persistent
,使 ANALYZE TABLE
收集的統計資訊更精確且更穩定,如 第 17.8.10.1 節,「設定持久性最佳化器統計資訊參數」中所述。當啟用 innodb_stats_persistent
時,在索引欄位資料發生重大變更之後執行 ANALYZE TABLE
很重要,因為統計資訊不會定期重新計算(例如在伺服器重新啟動後)。
如果啟用了 innodb_stats_persistent
,您可以透過修改 innodb_stats_persistent_sample_pages
系統變數來變更隨機深入檢查的次數。如果停用了 innodb_stats_persistent
,請改為修改 innodb_stats_transient_sample_pages
。
如需有關 InnoDB
中索引鍵分佈分析的更多資訊,請參閱 第 17.8.10.1 節,「設定持久性最佳化器統計資訊參數」和 第 17.8.10.3 節,「估計 InnoDB 表格的 ANALYZE TABLE 複雜度」。
MySQL 在聯結最佳化中使用索引基數估計值。如果聯結未以正確的方式最佳化,請嘗試執行 ANALYZE TABLE
。在少數情況下,ANALYZE TABLE
未產生足夠適用於特定表格的值,您可以將 FORCE INDEX
與查詢一起使用,以強制使用特定索引,或設定 max_seeks_for_key
系統變數,以確保 MySQL 偏好索引查閱而不是表格掃描。請參閱 第 B.3.5 節,「與最佳化器相關的問題」。
使用 HISTOGRAM
子句的 ANALYZE TABLE
可以管理表格欄位值的直方圖統計資訊。如需有關直方圖統計資訊的資訊,請參閱 第 10.9.6 節,「最佳化器統計資訊」。
提供以下直方圖操作
使用
UPDATE HISTOGRAM
子句的ANALYZE TABLE
會為指定的表格欄位產生直方圖統計資訊,並將它們儲存在資料字典中。此語法僅允許使用一個表格名稱。選用的
WITH
子句指定直方圖的儲存桶數量。N
BUCKETSN
的值必須是介於 1 到 1024 的整數。如果省略此子句,則儲存桶數量為 100。選用的
AUTO UPDATE
子句會在表格上啟用直方圖的自動更新。啟用後,此表格上的ANALYZE TABLE
陳述式會自動更新直方圖,使用上次針對此表格指定 (如果先前已針對此表格設定) 的WITH ... BUCKETS
相同的儲存桶數量。此外,當重新計算表格的持久性統計資訊時(請參閱 第 17.8.10.1 節,「設定持久性最佳化器統計資訊參數」),InnoDB
背景統計執行緒也會更新直方圖。MANUAL UPDATE
會停用自動更新,如果未指定,則這是預設設定。使用
DROP HISTOGRAM
子句的ANALYZE TABLE
會從資料字典中移除指定表格欄位的直方圖統計資訊。此語法僅允許使用一個表格名稱。
儲存的直方圖管理陳述式只會影響指定的欄位。考慮以下陳述式
ANALYZE TABLE t UPDATE HISTOGRAM ON c1, c2, c3 WITH 10 BUCKETS;
ANALYZE TABLE t UPDATE HISTOGRAM ON c1, c3 WITH 10 BUCKETS;
ANALYZE TABLE t DROP HISTOGRAM ON c2;
第一個陳述式會更新欄位 c1
、c2
和 c3
的直方圖,取代這些欄位的任何現有直方圖。第二個陳述式會更新 c1
和 c3
的直方圖,而 c2
的直方圖則不受影響。第三個陳述式會移除 c2
的直方圖,而 c1
和 c3
的直方圖則不受影響。
在建構直方圖時,若對使用者資料進行抽樣,並非所有數值都會被讀取;這可能導致遺失一些被認為重要的數值。在這種情況下,修改直方圖,或根據您自己的標準(例如完整資料集)明確設定您自己的直方圖可能會很有用。 ANALYZE TABLE
會使用與從 Information Schema tbl_name
UPDATE HISTOGRAM ON col_name
USING DATA 'json_data
'COLUMN_STATISTICS
表格顯示 HISTOGRAM
欄位值相同的 JSON 格式所提供的資料,來更新直方圖表格的欄位。當使用 JSON 資料更新直方圖時,只能修改一個欄位。
我們可以先在表格 t
的欄位 c1
上產生直方圖,藉此來說明 USING DATA
的用法,如下所示
mysql> ANALYZE TABLE t UPDATE HISTOGRAM ON c1;
+-------+-----------+----------+-----------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+-------+-----------+----------+-----------------------------------------------+
| h.t | histogram | status | Histogram statistics created for column 'c1'. |
+-------+-----------+----------+-----------------------------------------------+
1 row in set (0.00 sec)
我們可以在 COLUMN_STATISTICS
表格中看到產生的直方圖
mysql> TABLE information_schema.column_statistics\G
*************************** 1. row ***************************
SCHEMA_NAME: h
TABLE_NAME: t
COLUMN_NAME: c1
HISTOGRAM: {"buckets": [], "data-type": "int", "auto-update": false,
"null-values": 0.0, "collation-id": 8, "last-updated": "2024-03-26
16:54:43.674995", "sampling-rate": 1.0, "histogram-type": "singleton",
"number-of-buckets-specified": 100}
1 row in set (0.00 sec)
現在我們刪除直方圖,當我們檢查 COLUMN_STATISTICS
時,它是空的
mysql> ANALYZE TABLE t DROP HISTOGRAM ON c1;
+-------+-----------+----------+-----------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+-------+-----------+----------+-----------------------------------------------+
| h.t | histogram | status | Histogram statistics removed for column 'c1'. |
+-------+-----------+----------+-----------------------------------------------+
1 row in set (0.01 sec)
mysql> TABLE information_schema.column_statistics\G
Empty set (0.00 sec)
我們可以透過插入先前從 COLUMN_STATISTICS
表格的 HISTOGRAM
欄位取得的 JSON 表示法,來還原被刪除的直方圖,當我們再次查詢該表格時,可以看到直方圖已還原到之前的狀態
mysql> ANALYZE TABLE t UPDATE HISTOGRAM ON c1
-> USING DATA '{"buckets": [], "data-type": "int", "auto-update": false,
-> "null-values": 0.0, "collation-id": 8, "last-updated": "2024-03-26
-> 16:54:43.674995", "sampling-rate": 1.0, "histogram-type": "singleton",
-> "number-of-buckets-specified": 100}';
+-------+-----------+----------+-----------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+-------+-----------+----------+-----------------------------------------------+
| h.t | histogram | status | Histogram statistics created for column 'c1'. |
+-------+-----------+----------+-----------------------------------------------+
mysql> TABLE information_schema.column_statistics\G
*************************** 1. row ***************************
SCHEMA_NAME: h
TABLE_NAME: t
COLUMN_NAME: c1
HISTOGRAM: {"buckets": [], "data-type": "int", "auto-update": false,
"null-values": 0.0, "collation-id": 8, "last-updated": "2024-03-26
16:54:43.674995", "sampling-rate": 1.0, "histogram-type": "singleton",
"number-of-buckets-specified": 100}
加密表格(為了避免在統計資料中暴露資料)或 TEMPORARY
表格不支援直方圖產生。
直方圖產生適用於所有資料類型的欄位,但幾何類型(空間資料)和 JSON
除外。
直方圖可以為儲存和虛擬產生的欄位產生。
直方圖無法為單欄唯一索引所涵蓋的欄位產生。
直方圖管理陳述式會嘗試盡可能執行所要求的操作,並報告其餘的診斷訊息。例如,如果 UPDATE HISTOGRAM
陳述式命名多個欄位,但其中一些不存在或具有不支援的資料類型,則會為其他欄位產生直方圖,並為無效的欄位產生訊息。
直方圖會受到這些 DDL 陳述式的影響
DROP TABLE
會移除已刪除表格中欄位的直方圖。DROP DATABASE
會移除已刪除資料庫中任何表格的直方圖,因為該陳述式會刪除資料庫中的所有表格。RENAME TABLE
不會移除直方圖。相反地,它會重新命名已重新命名表格的直方圖,以與新的表格名稱相關聯。ALTER TABLE
會移除或修改欄位的陳述式會移除該欄位的直方圖。ALTER TABLE ... CONVERT TO CHARACTER SET
會移除字元欄位的直方圖,因為它們會受到字元集變更的影響。非字元欄位的直方圖則不受影響。
histogram_generation_max_mem_size
系統變數控制直方圖產生可用的最大記憶體量。全域和工作階段值可以在執行階段設定。
變更全域 histogram_generation_max_mem_size
值需要足夠的權限才能設定全域系統變數。變更工作階段 histogram_generation_max_mem_size
值需要足夠的權限才能設定受限的工作階段系統變數。請參閱第 7.1.9.1 節,「系統變數權限」。
如果讀取到記憶體中以產生直方圖的預估資料量超過 histogram_generation_max_mem_size
所定義的限制,MySQL 會對資料進行抽樣,而不是將所有資料讀取到記憶體中。抽樣會均勻分佈在整個表格中。MySQL 使用 SYSTEM
抽樣,這是一種頁面層級的抽樣方法。
可以查詢 Information Schema COLUMN_STATISTICS
表格的 HISTOGRAM
欄位中的 sampling-rate
值,以判斷為了建立直方圖所抽樣的資料比例。sampling-rate
是介於 0.0 和 1.0 之間的數字。值為 1 表示已讀取所有資料(沒有抽樣)。
以下範例示範抽樣。為了確保資料量超過範例目的的 histogram_generation_max_mem_size
限制,在為 employees
表格的 birth_date
欄位產生直方圖統計資料之前,會將限制設定為較低的值 (2000000 位元組)。
mysql> SET histogram_generation_max_mem_size = 2000000;
mysql> USE employees;
mysql> ANALYZE TABLE employees UPDATE HISTOGRAM ON birth_date WITH 16 BUCKETS\G
*************************** 1. row ***************************
Table: employees.employees
Op: histogram
Msg_type: status
Msg_text: Histogram statistics created for column 'birth_date'.
mysql> SELECT HISTOGRAM->>'$."sampling-rate"'
FROM INFORMATION_SCHEMA.COLUMN_STATISTICS
WHERE TABLE_NAME = "employees"
AND COLUMN_NAME = "birth_date";
+---------------------------------+
| HISTOGRAM->>'$."sampling-rate"' |
+---------------------------------+
| 0.0491431208869665 |
+---------------------------------+
sampling-rate
值為 0.0491431208869665 表示大約有 4.9% 的 birth_date
欄位資料被讀取到記憶體中,以產生直方圖統計資料。
InnoDB
儲存引擎為儲存在 InnoDB
表格中的資料提供其自己的抽樣實作。當儲存引擎未提供自己的抽樣實作時,MySQL 使用的預設抽樣實作需要完整表格掃描,這對於大型表格而言代價很高。InnoDB
抽樣實作透過避免完整表格掃描來改善抽樣效能。
可以使用 sampled_pages_read
和 sampled_pages_skipped
INNODB_METRICS
計數器來監控 InnoDB
資料頁面的抽樣。(如需一般 INNODB_METRICS
計數器使用資訊,請參閱第 28.4.21 節,「INFORMATION_SCHEMA INNODB_METRICS 表格」)。
以下範例示範抽樣計數器的使用方式,這需要在產生直方圖統計資料之前啟用計數器。
mysql> SET GLOBAL innodb_monitor_enable = 'sampled%';
mysql> USE employees;
mysql> ANALYZE TABLE employees UPDATE HISTOGRAM ON birth_date WITH 16 BUCKETS\G
*************************** 1. row ***************************
Table: employees.employees
Op: histogram
Msg_type: status
Msg_text: Histogram statistics created for column 'birth_date'.
mysql> USE INFORMATION_SCHEMA;
mysql> SELECT NAME, COUNT FROM INNODB_METRICS WHERE NAME LIKE 'sampled%'\G
*************************** 1. row ***************************
NAME: sampled_pages_read
COUNT: 43
*************************** 2. row ***************************
NAME: sampled_pages_skipped
COUNT: 843
此公式會根據抽樣計數器資料來近似抽樣率
sampling rate = sampled_page_read/(sampled_pages_read + sampled_pages_skipped)
根據抽樣計數器資料的抽樣率與 Information Schema COLUMN_STATISTICS
表格的 HISTOGRAM
欄位中的 sampling-rate
值大致相同。
如需有關為產生直方圖而執行的記憶體配置的資訊,請監控效能結構描述 memory/sql/histograms
工具。請參閱第 29.12.20.10 節,「記憶體摘要表格」。
ANALYZE TABLE
會清除 Information Schema INNODB_TABLESTATS
表格中的表格統計資料,並將 STATS_INITIALIZED
欄位設定為 Uninitialized
。下次存取表格時,會再次收集統計資料。