文件首頁
MySQL 9.0 參考手冊
相關文件 下載本手冊
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 參考手冊  /  ...  /  ANALYZE TABLE 陳述式

15.7.3.1 ANALYZE TABLE 陳述式

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 子句會從資料字典中移除指定資料表欄位的直方圖統計資訊。此語法僅允許一個資料表名稱。

此陳述式需要該資料表的 SELECTINSERT 權限。

ANALYZE TABLE 適用於 InnoDBNDBMyISAM 資料表。它不適用於檢視表。

如果啟用 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 節,「分割區維護」

在分析期間,InnoDBMyISAM 資料表會以讀取鎖定鎖定。

預設情況下,伺服器會將 ANALYZE TABLE 陳述式寫入二進位日誌,以便複製到複本。若要取消日誌記錄,請指定選用的 NO_WRITE_TO_BINLOG 關鍵字或其別名 LOCAL

ANALYZE TABLE 輸出

ANALYZE TABLE 會傳回結果集,其中包含下表中顯示的欄位。

欄位
資料表 資料表名稱
Op analyzehistogram
Msg_type statuserrorinfonotewarning
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 TABLEInnoDB 資料表上速度很快,但並非 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 BUCKETS 子句會指定直方圖的儲存桶數量。N 的值必須是 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;

第一個陳述式會更新欄位 c1c2c3 的直方圖,取代這些欄位的所有現有直方圖。第二個陳述式會更新 c1c3 的直方圖,讓 c2 的直方圖不受影響。第三個陳述式會移除 c2 的直方圖,讓 c1c3 的直方圖不受影響。

當取樣使用者資料以建立直方圖時,並非所有數值都會被讀取;這可能導致遺漏一些被認為重要的數值。在這種情況下,修改直方圖或根據您自己的標準(例如完整的資料集)明確設定您自己的直方圖可能很有用。ANALYZE TABLE tbl_name UPDATE HISTOGRAM ON col_name USING DATA 'json_data' 會使用與顯示來自 Information Schema 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_readsampled_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。下次存取表格時,會再次收集統計資料。