MySQL InnoDB儲存引擎更新Cardinality統計資訊的策略介紹

chenfeng發表於2018-06-19


在InnoDB儲存引擎中,Cardinality統計資訊的更新發生在兩個操作中:insert和update。
InnoDB儲存引擎內部對更新Cardinality資訊的策略為:持久化(PERSISTENT)與非持久化統計資料(TRANSIENT)。


持久化(PERSISTENT)統計資料,儲存在mysql.innodb_index_stats和mysql.innodb_table_stats中。
非持久化(TRANSIENT)統計資料,儲存在information_schema.statistics和information_schema.tables中。
前者是innodb表後者是memory表,他們受引數innodb_stats_persistent的控制。從MySQL 5.6.6開始,預設情況下,innodb_stats_persistent預設為ON,最佳化器統計資訊會保留在磁碟上。


對於持久化(persistent)統計資料策略:
表中1/10的資料已發生變化時,且設定了innodb_stats_auto_recalc和innodb_stats_persistent,則透過persistent方式更新統計資訊。
兩次申請統計資料收集要超過10S。

在5.6中,引入的一個新引數innodb_stats_auto_recalc用於控制是否進行自動統計資訊計算。當表上的記錄修改超過10%時,就會對統計資訊重新計算;這隻對在建表時開啟了innodb_stats_persistent或者指定了建表選項STATS_PERSISTEND=1生效,取樣page的個數透過引數innodb_stats_persistent_sample_pages來控制(實際讀取的page數會大於該值)。
innodb_stats_auto_recalc 這個引數控制著在表中行的數量改變超過10%的時候,是否重新收集統計資訊。這個收集的動作是非同步的,在執行完大的dml後,可能會過一段時間才重新收集統計資訊,如果想要及時的統計資訊,執行analyze命令去收集。


對於非持久化(transient)統計資料策略:
InnoDB檢測到自上次更新統計資訊以來表的1/16已被修改,透過transient方式更新統計資訊。
stat_modified_counter > 2000000000。
對於非持久化,第一種策略為自上次統計Cardinality資訊後,表中1/16的資料已經發生過變化,這時需要更新Cardinality資訊。第二種情況考慮的是,如果對錶中某一行資料頻繁地進行更新操作,這時表中的資料實際並沒有增加,實際發生變化的還是這一行資料,則第一種更新策略就無法適用這種情況。故在InnoDB儲存引擎內部有一個計數器stat_modified_counter,用來表示發生變化的次數。當stat_modified_counter大於2000000000時,同樣需要更新Cardinality資訊。



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15498/viewspace-2156325/,如需轉載,請註明出處,否則將追究法律責任。

相關文章