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
子句會指定直方圖的儲存桶數量。N
BUCKETSN
的值必須是 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
。下次存取表格時,會再次收集統計資料。