MySQL InnoDB配置統計信息
本文檔介紹如何為InnoDB表配置持久性和非持久性統計信息。
持久化統計信息在服務器重新啟動時保持不變,從而使執行計划和查詢性能更加穩定。持久化統計信息還提供了控制和靈活性以及這些額外的好處:
-
可以使用
innodb_stats_auto_recalc
配置選項來控制在對表進行實質性更改后是否自動更新統計信息。 -
可以將
STATS_PERSISTENT
,STATS_AUTO_RECALC
和STATS_SAMPLE_PAGES
子句與CREATE TABLE和ALTER TABLE語句一起使用,以配置各個表的優化程序統計信息。 -
可以在
mysql.innodb_table_stats
和mysql.innodb_index_stats
表中查詢優化程序統計信息數據。 -
可以查看
mysql.innodb_table_stats
和mysql.innodb_index_stats
表的last_update列,以查看最后一次更新統計信息的時間。 -
在不需要修改數據庫的情況下,可以手動修改
mysql.innodb_table_stats
和mysql.innodb_index_stats
表,以強制執行特定的執行計划或測試備用執行計划。
默認情況下啟用持久優化程序統計信息功能innodb_stats_persistent = ON
。
非持久化統計信息在每次重新啟動服務器和其他一些操作后清除,並在下一個表訪問時重新計算。因此,在重新計算統計數據時可能會產生不同的估計值,從而導致執行計划中的不同選擇和查詢性能的變化。
本文檔還提供了有關估計ANALYZE TABLE
復雜性的信息,這在嘗試實現精確統計信息和ANALYZE TABLE執行時間之間的平衡時可能很有用。
1. 配置持久化(Persistent)統計信息參數
innodb_stats_persistent
- 參數含義:是否啟用持久化統計信息功能
- 默認值:ON
持久化統計信息功能通過將統計信息存儲到磁盤並使其在服務器重新啟動期間保持不變來提高執行計划的穩定性,以便優化器更有可能每次為給定查詢做出一致的選擇。
當innodb_stats_persistent = ON
或使用STATS_PERSISTENT = 1
創建或更改單個表時,統計信息將持久保存到磁盤。innodb_stats_persistent
默認啟用。
要恢復使用非持久化統計信息,可以使用ALTER TABLE tbl_name STATS_PERSISTENT = 0
語句修改表。
1.1 配置自動觸發更新統計信息參數
innodb_stats_auto_recalc
- 參數含義:是否自動觸發更新統計信息
- 觸發閾值:
- 表修改時,確認變化的數據是否超過10%,超過自動收集統計信息
- 表,索引統計信息是持久化存儲
- 默認值:ON
由於自動統計信息重新計算(發生在后台)是異步,在運行影響超過10%的表的DML操作時(即使innodb_stats_auto_recalc
啟用后),可能不會立即重新計算統計信息 。在某些情況下,統計重新計算可能會延遲幾秒鍾(10s)。如果在更改表的重要部分之后立即需要最新統計信息,請運行ANALYZE TABLE以啟動統計信息的同步(前台)重新計算。
如果禁用了innodb_stats_auto_recalc
,請在對索引列進行實質性更改后,通過為每個適用的表發出ANALYZE TABLE
語句來確保統計信息的准確性。
在表上添加索引或者添加刪除索引中的列時,將自動計算索引統計信息並將其添加到innodb_index_stats表,不受innodb_stats_auto_recalc的值影響。
1.2 配置每張表的統計參數
innodb_stats_persistent
,innodb_stats_auto_recalc
和innodb_stats_persistent_sample_pages
是全局配置選項。
若要覆蓋這些系統范圍的設置並為各個表配置統計信息參數,可以在CREATE TABLE
或ALTER TABLE
語句中定義STATS_PERSISTENT
,STATS_AUTO_RECALC
和STATS_SAMPLE_PAGES
子句。
- STATS_PERSISTENT
指定是否為InnoDB表啟用持久統計信息。- DEFAULT:表示表的持久統計信息設置由
innodb_stats_persistent
配置選項確定 - 1:表示啟用表的持久統計信息
- 0:關閉此功能
- DEFAULT:表示表的持久統計信息設置由
- STATS_AUTO_RECALC
指定是否自動重新計算InnoDB表的持久統計信息。- DEFAULT:表示表的持久統計信息設置由innodb_stats_auto_recalc配置選項確定
- 1:表示表中10%的數據發生更改時將重新計算統計信息
- 0:禁用自動重新計算此表
- STATS_SAMPLE_PAGES
指定在估計索引列的基數和其他統計信息時要采樣的索引頁數
示例
CREATE TABLE `t1` ( `id` int(8) NOT NULL auto_increment, `data` varchar(255), `date` datetime, PRIMARY KEY (`id`), INDEX `DATE_IX` (`date`) ) ENGINE=InnoDB, STATS_PERSISTENT=1, STATS_AUTO_RECALC=1, STATS_SAMPLE_PAGES=25;
1.3 配置InnoDB優化器統計信息的采樣頁數參數
innodb_stats_persistent_sample_pages
- 參數含義:配置持久化統計信息采樣的頁數
- 默認值:20
在什么情況下需要修改此參數呢:
-
統計信息不夠准確,優化器選擇次優計划
如果確定統計信息不夠准確,則應增加innodb_stats_persistent_sample_pages
的值,直到統計估計值足夠准確。但是,過多地增加innodb_stats_persistent_sample_pages可能會導致ANALYZE TABLE運行緩慢。 -
ANALYZE TABLE太慢
在這種情況下,應減少innodb_stats_persistent_sample_pages,直到ANALYZE TABLE執行時間可以接受。但是,過多地降低該值可能會導致生成不准確的統計信息和次優查詢執行計划的問題。
1.4 包含Delete-marked
的記錄參數
innodb_stats_include_delete_marked
- 參數含義:在MySQL 5.7.16中引入的此參數,默認為不啟用,表示在未提交的事務有
從表中刪除行
,則InnoDB在收集統計信息時,將會排除這些delete_marked
行。這可能會導致除READ UNCOMMITTED
之外的事務隔離級別的事務,運行的不是最佳的執行計划。
為了避免這種情況,可以啟用innodb_stats_include_delete_marked
以確保在計算持久化統計信息時InnoDB包含Delete-marked
記錄。 - 默認值:OFF
1.5 InnoDB持久化統計表
持久化統計信息功能依賴於mysql數據庫中的內部表,名為innodb_table_stats
和innodb_index_stats
。
這些表在所有安裝,升級和源代碼構建過程中自動設置。
mysql.innodb_table_stats
+--------------------------+---------------------+------+-----+-------------------+-----------------------------+-------------------------- | Field | Type | Null | Key | Default | Extra |注釋 +--------------------------+---------------------+------+-----+-------------------+-----------------------------+-------------------------- | database_name | varchar(64) | NO | PRI | NULL | |數據庫名稱 | table_name | varchar(199) | NO | PRI | NULL | |表名,分區名或子分區名 | last_update | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |最后一次更新統計信息時間 | n_rows | bigint(20) unsigned | NO | | NULL | |表中的行數 | clustered_index_size | bigint(20) unsigned | NO | | NULL | |主鍵索引大小(單位page) | sum_of_other_index_sizes | bigint(20) unsigned | NO | | NULL | |其他索引總大小(單位page) +--------------------------+---------------------+------+-----+-------------------+-----------------------------+--------------------------
mysql.innodb_index_stats
+------------------+---------------------+------+-----+-------------------+-----------------------------+---------------------------- | Field | Type | Null | Key | Default | Extra | 注釋 +------------------+---------------------+------+-----+-------------------+-----------------------------+---------------------------- | database_name | varchar(64) | NO | PRI | NULL | | 數據庫名稱 | table_name | varchar(199) | NO | PRI | NULL | | 表名,分區名或子分區名 | index_name | varchar(64) | NO | PRI | NULL | | 索引名稱 | last_update | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP | 最后一次更新統計信息的時間 | stat_name | varchar(64) | NO | PRI | NULL | | 統計信息的名稱,其值在stat_value列中報告 | stat_value | bigint(20) unsigned | NO | | NULL | | 在stat_name列中命名的統計信息的值 | sample_size | bigint(20) unsigned | YES | | NULL | | 在stat_value列中提供的估計值的頁面采樣數 | stat_description | varchar(1024) | NO | | NULL | | 在stat_name列中命名的統計信息的描述 +------------------+---------------------+------+-----+-------------------+-----------------------------+----------------------------
start_name: 為size時 :此時stat_value顯示索引的page數量。 為n_leaf_pages時 :此時stat_value顯示葉子節點的數量。 為n_diff_pfxNN時 :顯示索引字段上唯一值的數量
【注意】:
innodb_table_stats和innodb_index_stats表是普通表,可以手動更新。
如果手動更新統計信息,請發出FLUSH TABLE tbl_name
命令以使MySQL重新加載更新的統計信息。
1.6 InnoDB持久化統計表示例
創建表t1包含主索引(列a,b)二級索引(列c,d)和唯一索引(列e,f):
CREATE TABLE t1 ( a INT, b INT, c INT, d INT, e INT, f INT, PRIMARY KEY (a, b), KEY i1 (c, d), UNIQUE KEY i2uniq (e, f) ) ENGINE=INNODB;
插入5行數據后
insert into t1 select 1,1,10,11,100,101; insert into t1 select 1,2,10,11,200,102; insert into t1 select 1,3,10,11,100,103; insert into t1 select 1,4,10,12,200,104; insert into t1 select 1,5,10,12,100,105; SELECT * FROM t1; +---+---+------+------+------+------+ | a | b | c | d | e | f | +---+---+------+------+------+------+ | 1 | 1 | 10 | 11 | 100 | 101 | | 1 | 2 | 10 | 11 | 200 | 102 | | 1 | 3 | 10 | 11 | 100 | 103 | | 1 | 4 | 10 | 12 | 200 | 104 | | 1 | 5 | 10 | 12 | 100 | 105 | +---+---+------+------+------+------+
要立即更新統計信息,請運行ANALYZE TABLE
。(如果啟用了innodb_stats_auto_recalc,則假定已達到更改的表行的10%閾值,則會在幾秒鍾內自動更新統計信息)
mysql> ANALYZE TABLE t1; +---------+---------+----------+----------+ | Table | Op | Msg_type | Msg_text | +---------+---------+----------+----------+ | test.t1 | analyze | status | OK | +---------+---------+----------+----------+ 1 row in set (0.02 sec)
表最后一次收集統計信息時間為2018-08-29 11:10:03
,表的行數為 5,主鍵索引大小為 1page,其他索引的總大小為 2 page。
mysql> select * from mysql.innodb_table_stats t where t.database_name='test' and t.table_name='t1'\G *************************** 1. row *************************** database_name: test table_name: t1 last_update: 2018-08-29 11:10:03 n_rows: 5 clustered_index_size: 1 sum_of_other_index_sizes: 2 1 row in set (0.00 sec)
innodb_index_stats
表包含每個索引的多行。 innodb_index_stats表中的每一行都提供與特定索引統計信息相關的數據,該統計信息在stat_name列中命名並在stat_description列中進行了描述。 例如:
mysql> select * from mysql.innodb_index_stats t where t.database_name='test' and t.table_name='t1'; +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+ | database_name | table_name | index_name | last_update | stat_name | stat_value | sample_size | stat_description | +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+ | test | t1 | PRIMARY | 2018-08-29 11:10:03 | n_diff_pfx01 | 1 | 1 | a | | test | t1 | PRIMARY | 2018-08-29 11:10:03 | n_diff_pfx02 | 5 | 1 | a,b | | test | t1 | PRIMARY | 2018-08-29 11:10:03 | n_leaf_pages | 1 | NULL | Number of leaf pages in the index | | test | t1 | PRIMARY | 2018-08-29 11:10:03 | size | 1 | NULL | Number of pages in the index | | test | t1 | i1 | 2018-08-29 11:10:03 | n_diff_pfx01 | 1 | 1 | c | | test | t1 | i1 | 2018-08-29 11:10:03 | n_diff_pfx02 | 2 | 1 | c,d | | test | t1 | i1 | 2018-08-29 11:10:03 | n_diff_pfx03 | 2 | 1 | c,d,a | | test | t1 | i1 | 2018-08-29 11:10:03 | n_diff_pfx04 | 5 | 1 | c,d,a,b | | test | t1 | i1 | 2018-08-29 11:10:03 | n_leaf_pages | 1 | NULL | Number of leaf pages in the index | | test | t1 | i1 | 2018-08-29 11:10:03 | size | 1 | NULL | Number of pages in the index | | test | t1 | i2uniq | 2018-08-29 11:10:03 | n_diff_pfx01 | 2 | 1 | e | | test | t1 | i2uniq | 2018-08-29 11:10:03 | n_diff_pfx02 | 5 | 1 | e,f | | test | t1 | i2uniq | 2018-08-29 11:10:03 | n_leaf_pages | 1 | NULL | Number of leaf pages in the index | | test | t1 | i2uniq | 2018-08-29 11:10:03 | size | 1 | NULL | Number of pages in the index | +---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+ 14 rows in set (0.00 sec)
stat_name
列顯示以下類型的統計信息:
- 如果
stat_name = size
,則stat_value列顯示索引中的總大小(單位page)。 - 如果
stat_name = n_leaf_pages
,則stat_value列顯示索引中的葉子頁數。 - 如果stat_name = n_diff_pfx01,stat_value列顯示索引第一列中的不同值的數量。 當
stat_name = n_diff_pfx02
,stat_value列顯示索引前兩列中的不同值的數量,依此類推。 此外,在stat_name = n_diff_pfxNN的情況下,stat_description列顯示了計算的索引列。
進一步說明基數數據的n_diff_pfxNN
統計量:
表t1使用主索引(列a,b),輔助索引(列c,d)和唯一索引(列e,f)。
-
對於PRIMARY索引,有兩個n_diff%行。行數等於索引中的列數。
【注意】
對於非唯一索引,索引會附加主鍵列。-
index_name = PRIMARY
和stat_name = n_diff_pfx01
stat_value
為1,表示索引的第一列中存在單個不同的值(列a)。 通過查看表t1中的列a中的數據來確認列a中的不同值的數量,其中存在單個不同的值(1)。 計數列(a)顯示在結果集的stat_description
列中。 -
index_name = PRIMARY
和stat_name = n_diff_pfx02
stat_value
為5,表示索引(a,b)的兩列中有五個不同的值。 通過查看表t1中列a和b中的數據來確認列a和b中的不同值的數量,其中有五個不同的值:(1,1),(1,2),(1,3) ,(1,4)和(1,5)。 計數列(a,b)顯示在結果集的stat_description
列中。
-
-
對於二級索引(i1),有四個n_diff%行
對於二級索引(i1),有四個n_diff%行。 僅為輔助索引(c,d)定義了兩列,但是輔助索引有四個n_diff%行,因為InnoDB使用主鍵為所有非唯一索引添加后綴。-
index_name = i1
和stat_name = n_diff_pfx01
stat_value為1,表示索引的第一列(列c)中存在單個不同的值。通過查看表t1中列c中的數據來確認列c中的不同值的數量,其中存在單個不同的值:(10)。計數列(c)顯示在結果集的stat_description列中。 -
index_name = i1和stat_name = n_diff_pfx02
stat_value為2,表示索引(c,d)的前兩列中有兩個不同的值。通過查看表t1中列c和d中的數據來確認列c和d中的不同值的數量,其中存在兩個不同的值:(10,11)和(10,12)。計數列(c,d)顯示在結果集的stat_description列中。 -
index_name = i1和stat_name = n_diff_pfx03
stat_value為2,表示索引的前三列中有兩個不同的值(c,d,a)。通過查看表c1中的列c,d和a中的數據來確認列c,d和a中的不同值的數量,其中有兩個不同的值:(10,11,1)和(10, 12,1)。計數列(c,d,a)顯示在結果集的stat_description列中。 -
index_name = i1和stat_name = n_diff_pfx04
stat_value為5,表示索引的四列中有五個不同的值(c,d,a,b)。通過查看表t1中列c,d,a和b中的數據來確認列c,d,a和b中的不同值的數量,其中有五個不同的值:(10,11,1,1),(10,11,1,2),(10,11,1,3),(10,12,1,4)和(10,12,1,5)。計數列(c,d,a,b)顯示在結果集的stat_description列中。
-
-
對於唯一索引(i2uniq),有兩個n_diff%行
-
index_name = i2uniq和stat_name = n_diff_pfx01
stat_value為2,表示索引的第一列中有兩個不同的值(列e)。 通過查看表t1中的列e中的數據來確認列e中的不同值的數量,其中存在兩個不同的值:(100)和(200)。 計數列(e)顯示在結果集的stat_description列中。 -
index_name = i2uniq和stat_name = n_diff_pfx02
stat_value為5,表示索引的兩列中有五個不同的值(e,f)。 通過查看表t1中的列e和f中的數據來確認列e和f中的不同值的數量,其中存在五個不同的值:(100,101),(200,102),(100,103),(200,104)和(100105)。 計數列(e,f)顯示在結果集的stat_description列中。
-
1.7 使用innodb_index_stats表查詢索引大小
可以使用innodb_index_stats表查詢表,分區或子分區的索引大小,例如:
SELECT SUM(stat_value) pages, index_name, SUM(stat_value) * @@innodb_page_size size FROM mysql.innodb_index_stats WHERE table_name = 't1' AND database_name = 'test' AND stat_name = 'size' GROUP BY index_name; +-------+------------+-------+ | pages | index_name | size | +-------+------------+-------+ | 1 | PRIMARY | 16384 | | 1 | i1 | 16384 | | 1 | i2uniq | 16384 | +-------+------------+-------+ 3 rows in set (0.00 sec)
對於分區或子分區,可以使用修改的WHERE子句的相同查詢來查詢索引大小。
例如,以下查詢檢索表t1的分區的索引大小:
SELECT SUM(stat_value) pages, index_name, SUM(stat_value) * @@innodb_page_size size FROM mysql.innodb_index_stats WHERE table_name LIKE 't1#P%' AND stat_name = 'size' GROUP BY index_name;
2. 配置非持久化(Non-Persistent)統計信息參數
當innodb_stats_persistent = OFF
或使用STATS_PERSISTENT = 0
創建或更改單張表時,統計信息不會保留到磁盤。 相反,統計信息存儲在內存中,並在服務器關閉時丟失。 某些業務和某些條件下也會定期更新統計數據。
從MySQL 5.6.6開始,默認情況下,統計信息會持久保存到磁盤,由innodb_stats_persistent
配置選項啟用。
2.1 優化器統計信息更新
innodb_stats_on_metadata
- 參數含義:表示是否InnoDB在(如SHOW TABLE STATUS)或訪問INFORMATION_SCHEMA.TABLES或INFORMATION_SCHEMA.STATISTICS)操作期間更新統計信息。
- 默認值:OFF
保留禁用的設置可以提高具有大量表或索引的模式的訪問速度。它還可以提高涉及InnoDB表的查詢的執行計划的穩定性。
如果啟用此參數,在以下情況下更新非持久化統計信息:
-
運行
ANALYZE TABLE
-
運行
SHOW TABLE STATUS
,SHOW INDEX
或查詢INFORMATION_SCHEMA.TABLES
或INFORMATION_SCHEMA.STATISTICS
表並啟用innodb_stats_on_metadata
選項。默認情況下,在MySQL 5.6.6中啟用持久化統計信息時,
innodb_stats_on_metadata
的默認設置已更改為OFF
。 啟用innodb_stats_on_metadata
可能會降低大表或索引的訪問速度,並降低涉及InnoDB表的查詢的執行計划的穩定性。 使用SET語句全局配置innodb_stats_on_metadata。SET GLOBAL innodb_stats_on_metadata=ON
【注意】
innodb_stats_on_metadata僅在統計信息配置為非持久化時(禁用innodb_stats_persistent時)適用。 -
默認設置,在mysql客戶端啟用
--auto-rehash
選項的。auto-rehash
選項會導致打開所有InnoDB表,並且open table操作會導致重新計算統計信息。
要改善mysql客戶端的啟動時間並更新統計信息,可以使用--disable-auto-rehash選項關閉自動重新連接。 auto-rehash功能可以為交互式用戶自動完成數據庫,表和列名稱的名稱。 -
打開一張表
-
自上次更新統計信息以來,InnoDB檢測到表中1/16數據已被修改。
2.2 配置采樣頁數參數
innodb_stats_transient_sample_pages
- 參數含義:表示每次隨機采樣頁的數量
- 默認值:8
當innodb_stats_persistent = 0
時,innodb_stats_transient_sample_pages
的值會影響所有InnoDB表和索引的索引采樣。更改索引樣本大小時,請注意以下潛在的重大影響:
-
像1或2這樣的小值可能導致基數估計不准確。
-
增加
innodb_stats_transient_sample_pages
值可能需要更多磁盤讀取。遠大於8(例如,100)的值可能導致打開表或執行SHOW TABLE STATUS所花費的時間顯着減慢。 -
優化器可能會根據索引選擇性的不同估計選擇非常不同的查詢計划。
3. Analyze Table復雜性度
InnoDB表的ANALYZE TABLE復雜性度決於:
-
采樣的頁數,由
innodb_stats_persistent_sample_pages
定義。 -
表中索引列的數量
-
分區數量。如果表沒有分區,則分區數被視為1。
使用這些參數,估計ANALYZE TABLE復雜性度近似公式為:
innodb_stats_persistent_sample_pages * 表中索引列的數量 * 分區數
, 通常,結果值越大,ANALYZE InnoDB TABLE的執行時間越長。
【注意】
innodb_stats_persistent_sample_pages
定義在全局級別采樣的頁數。 要設置單個表的采樣頁數,請使用帶有CREATE TABLE或ALTER TABLE的STATS_SAMPLE_PAGES
選項。如果
innodb_stats_persistent = OFF
,則采樣的頁數由innodb_stats_transient_sample_pages
定義。
有關估計ANALYZE TABLE復雜性的更深入方法,請考慮以下示例。
在Big O
表示法中,ANALYZE TABLE復雜度描述為:
O(n_sample * (n_cols_in_uniq_i + n_cols_in_non_uniq_i + n_cols_in_pk * (1 + n_non_uniq_i)) * n_part)
-
n_sample是采樣的頁數(由innodb_stats_persistent_sample_pages定義)
-
n_cols_in_uniq_i是所有唯一索引中所有列的總數(不包括主鍵列)
-
n_cols_in_non_uniq_i是所有非唯一索引中所有列的總數
-
n_cols_in_pk是主鍵中的列數(如果未定義主鍵,InnoDB在內部創建單列主鍵)
-
n_non_uniq_i是表中非唯一索引的數量
-
n_part是分區數。 如果未定義分區,則該表被視為單個分區。
現在,創建下面的表(表t),它有一個主鍵(2列),一個唯一索引(2列)和兩個非唯一索引(每個2列):
CREATE TABLE t ( a INT, b INT, c INT, d INT, e INT, f INT, g INT, h INT, PRIMARY KEY (a, b), UNIQUE KEY i1uniq (c, d), KEY i2nonuniq (e, f), KEY i3nonuniq (g, h) ); SELECT t.index_name, t.last_update, t.stat_name, t.stat_description FROM mysql.innodb_index_stats t WHERE t.database_name = 'test' AND t.table_name = 't' AND t.stat_name LIKE 'n_diff_pfx%'; +------------+---------------------+--------------+------------------+ | index_name | last_update | stat_name | stat_description | +------------+---------------------+--------------+------------------+ | PRIMARY | 2018-08-29 13:38:37 | n_diff_pfx01 | a | | PRIMARY | 2018-08-29 13:38:37 | n_diff_pfx02 | a,b | | i1uniq | 2018-08-29 13:38:37 | n_diff_pfx01 | c | | i1uniq | 2018-08-29 13:38:37 | n_diff_pfx02 | c,d | | i2nonuniq | 2018-08-29 13:38:37 | n_diff_pfx01 | e | | i2nonuniq | 2018-08-29 13:38:37 | n_diff_pfx02 | e,f | | i2nonuniq | 2018-08-29 13:38:37 | n_diff_pfx03 | e,f,a | | i2nonuniq | 2018-08-29 13:38:37 | n_diff_pfx04 | e,f,a,b | | i3nonuniq | 2018-08-29 13:38:37 | n_diff_pfx01 | g | | i3nonuniq | 2018-08-29 13:38:37 | n_diff_pfx02 | g,h | | i3nonuniq | 2018-08-29 13:38:37 | n_diff_pfx03 | g,h,a | | i3nonuniq | 2018-08-29 13:38:37 | n_diff_pfx04 | g,h,a,b | +------------+---------------------+--------------+------------------+
根據上面顯示的索引統計數據和表定義,可以確定以下值:
-
n_cols_in_uniq_i,所有唯一索引中不包括主鍵列的所有列的總數為
2
(c和d) -
n_cols_in_non_uniq_i,所有非唯一索引中所有列的總數,為
4
(e,f,g和h) -
n_cols_in_pk,主鍵中的列數為
2
(a和b) -
n_non_uniq_i,表中非唯一索引的數量是
2
(i2nonuniq和i3nonuniq)) -
n_part,分區數,是
1
。
根據公式計算掃描的葉頁數:
O(n_sample * (n_cols_in_uniq_i + n_cols_in_non_uniq_i + n_cols_in_pk * (1 + n_non_uniq_i)) * n_part) innodb_stats_persistent_sample_pages = 20 n_cols_in_uniq_i = 2 n_cols_in_non_uniq_i =4 n_cols_in_pk = 2 n_non_uniq_i = 2 n_part = 1
估計表t讀取 20 * (2 + 4 + 2 *(1 + 2) * 16384 /1024 = 3932160字節,大約4M。