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子句會從資料字典中移除指定資料表欄位的直方圖統計資訊。此語法僅允許一個資料表名稱。
此陳述式需要該資料表的 SELECT 和 INSERT 權限。
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 |
資訊訊息 |
ANALYZE TABLE 不帶任何 HISTOGRAM 子句會執行索引鍵分佈分析,並將分佈儲存到資料表。任何現有的直方圖統計資訊都不會受到影響。
如果資料表自上次索引鍵分佈分析以來沒有變更,則不會再次分析資料表。
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 節,「與最佳化工具相關的問題」。
ANALYZE TABLE 帶有 HISTOGRAM 子句可以管理資料表欄位值的直方圖統計資訊。有關直方圖統計資訊的詳細資訊,請參閱 第 10.9.6 節,「最佳化工具統計資料」。
提供以下直方圖操作
ANALYZE TABLE帶有UPDATE HISTOGRAM子句會為指定的資料表欄位產生直方圖統計資訊,並將其儲存在資料字典中。此語法僅允許一個資料表名稱。選用的
WITH子句會指定直方圖的儲存桶數量。NBUCKETSN的值必須是 1 到 1024 範圍內的整數。如果省略此子句,則儲存桶數量為 100。選用的
AUTO UPDATE子句會啟用資料表上直方圖的自動更新。啟用後,此資料表上的ANALYZE TABLE陳述式會自動更新直方圖,如果先前已為此資料表設定,則會使用上次由WITH ... BUCKETS指定的相同儲存桶數量。此外,當重新計算資料表的持續統計資訊時(請參閱 第 17.8.10.1 節,「設定持續最佳化工具統計資料參數」),InnoDB背景統計執行緒也會更新直方圖。MANUAL UPDATE會停用自動更新,如果未指定則為預設設定。ANALYZE TABLE帶有DROP HISTOGRAM子句會從資料字典中移除指定資料表欄位的直方圖統計資訊。此語法僅允許一個資料表名稱。
儲存的直方圖管理陳述式僅影響指定的欄位。請考慮以下陳述式
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 表示已將 birth_date 資料行中約 4.9% 的資料讀取到記憶體中,以產生直方圖統計資料。
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。下次存取表格時,會再次收集統計資料。