MySQL查詢優化器的執行計劃是根據統計資訊中鍵值的分布選擇合适的索引,這是基于索引的選擇性的。innodb通過抽樣的方式來計算統計資訊,首先随機的讀取少量的索引頁面,然後以此為樣本計算索引的統計資訊。老的innodb預設樣本頁面數為8,新版本可以通過innodb_stats_transient_sample_pages(5.6.3之前是innodb_stats_sample_pages)來設定樣本頁的數量。樣本頁的數量設定的更大,理論上來說是可以得到更準确的統計資訊,特别是對于超大的表。但是具體設定多大合适還是需要根據實際情況
innodb索引的統計資訊存儲方式有兩種,一種是非持久性存儲,既存儲在記憶體中,如果伺服器重新開機就會丢失;一種是持久性存儲,即存儲到磁盤上,可以永久儲存。通過參數innodb_stats_persistent來控制。在MySQL5.6.6之後,預設是持久性存儲。
兩種存儲方式:
1ã 非持久性存儲,通過設定innodb_stats_persistent=OFF或者使用
STATS_PERSISTENT=0建立,通過以下操作可以觸發計算統計資訊:
a)
執行analyze table
b)
在使用show table status、show index等指令的時候,或者在查詢系統表INFORMATION_SCHEMA.TABLES 和 INFORMATION_SCHEMA.STATISTICS的時候。需要一個參數控制是否會觸發更新統計資訊,innodb_stats_on_metadata=on時。
這裡需要注意的是,資料庫中有大量的表或者索引的時候,會給資料庫的IO帶來更大的壓力;并且如果頻繁的更新統計資訊,MySQL的執行計劃的穩定性也會受到影響。
c)
在啟動mysql用戶端的時候采用--auto-rehash參數。
d)
一個表首次被打開的時候。
e)
表發生非常大的變化的時候(大小變化超過1/16或者新插入20億行資料)。
2ã 持久性存儲,設定innodb_stats_persistent=ON,或者STATS_PERSISTENT=1建立。
持久化的資訊存儲在MySQL的系統表mysql.innodb_table_stats
和mysql.innodb_index_stats 中。
因為是持久性存儲到磁盤上,是以在表一段時間之後或者是進行大的改動的時候需要手動執行analyze table來更新統計資訊。
總結:建議設定持久性存儲到磁盤上,可以得到更穩定的執行計劃,并且在系統重新開機之後可以更快速的生成統計資訊。但是需要周期性的執行analyze table來手動更新統計資訊,否則統計資訊永遠不變。