MySQL InnoDB的索引統計信息在什麼時候更新呢? 或者說什麼事件會觸發InnoDB索引的統計信息更新呢?下麵結合參考資料When Does InnoDB Update the Index Statistics? (Doc ID 1463718.1)[1]簡單總結梳理一下(文中大部分知識點來自 ...
MySQL InnoDB的索引統計信息在什麼時候更新呢? 或者說什麼事件會觸發InnoDB索引的統計信息更新呢?下麵結合參考資料When Does InnoDB Update the Index Statistics? (Doc ID 1463718.1)[1]簡單總結梳理一下(文中大部分知識點來自參考資料)。
1: ANALYZE TABLE命令
ANALYZE TABLE命令會顯式強制更新表的索引統計信息。例子:
ANALYZE TABLE <TABLE_NAME>;
2:OPTIMIZE TABLE命令
對InnoDB的表執行OPTIMIZE TABLE命令時, OPTIMIZE TABLE重新組織表的數據和關聯索引數據的物理存儲,以減少存儲空間並提高訪問表時的I/O效率。通俗點理解就是碎片整理。它會重建表並執行ANALYZE TABLE命令,因此索引的統計信息也會被更新。
3:元數據查看觸發
如果您開啟了瞬態統計信息(transient statistics)並且innodb_stats_on_metadata參數為ON(MySQL 5.5及更早版本中的預設值,但在MySQL 5.6及更高版本中不是預設值)的話,那麼InnoDB會在以下情況下更新索引的統計信息:
查詢元數據信息的SQL語句:
SHOW TABLE STATUS SHOW INDEX
或者當你訪問INFORMATION_SCHEMA下一些表時也會觸發統計信息更新,例如:
TABLES STATISTICS。
其實實際環境中,這種條件很少觸發索引更新統計信息,因為它的條件一般很難滿足,正常情況下,這些參數都不會這樣設置。
另外這裡補充一下transient statistics的知識:
關於瞬態統計信息(transient statistics), 其實transient statistics也叫non-persistent optimizer statistics,翻譯成非持久統計信息,它是當innodb_stats_persistent=OFF 或使用 STATS_PERSISTENT=0時,創建或更改單個表時,優化程式統計信息不會保存到磁碟。相反,統計信息存儲在記憶體中,併在伺服器關閉時丟失。統計信息也會通過某些操作和特定條件下定期更新。
4 統計信息自動更新
對於使用瞬態統計信息的表,統計信息是在首次打開表時計算的。這包括FLUSH TABLE和FLUSH TABLES WITH READ LOCK。
此外,當表的有大量數據發生變化時,InnoDB還將觸發重新計算索引統計信息。邏輯取決於使用的是持久統計信息還是瞬態統計信息:
持久統計信息:為表啟用 STATS_AUTO_RECALC(預設情況下設置為預設啟用的 innodb_stats_auto_recalc 值)時,當 1/10 (10%) 行發生更改時,索引統計信息將更新,限製為每次更新之間必須至少經過 10 秒。
瞬態統計信息:自上次更新統計信息以來,表中至少 1/16 (6.25%) 的行已被修改。
另外,關於transient statistics,其實有些版本還是有一些Bug的,例如Bug #98546 Transient indexes statistics are updated in foreground causing performance issue
參考資料
1: https://support.oracle.com/epmos/faces/DocumentDisplay?_afrLoop=342584987828510&id=1463718.1&_afrWindowMode=0&_adf.ctrl-state=5hdz2z4vn_4,