GreatSQL統計資訊相關知識點

GreatSQL發表於2024-04-24

相關知識點:

INNODB_STATS_PERSIST=ON或用STATS_PERSIST=1定義單個表時,最佳化器統計資訊將持久化到磁碟。預設情況下,innodb_stats_persistent是啟用的。

持久統計資訊儲存在mysql.innodb_table_statsmysql.innodb_index_stats表中。

預設情況下啟用的innodb_stats_auto_recalc變數控制當表中超過10%的行發生更改時是否自動計算統計資訊。可以透過在建立或更改表時指定STATS_AUTO_RECALC子句來為單個表配置自動統計資料重新計算。

由於在後臺進行的自動統計資料重新計算的非同步性質,即使啟用了innodb_stats_auto_recalc,在執行影響表10%以上的DML操作後,也不會立即重新計算統計資料。在某些情況下,統計資料的重新計算可能會延遲幾秒鐘。如果立即需要最新的統計資料,執行ANALYZE TABLE以啟動統計資料的同步(前臺)重新計算。

如果禁用innodb_stats_auto_recalc則可以透過在對索引列進行大量更改後執行ANALYZE TABLE語句來確保最佳化器統計資訊的準確性。

INNODB_STATS_PERSIST=OFF或使用STATS_PERSIST=0建立或更改單個表時,最佳化器統計資訊不會持久化到磁碟。相反,統計資訊儲存在記憶體中,當伺服器關閉時會丟失。統計資料也會透過某些操作和在某些條件下定期更新。

當向現有表中新增索引時,或者當新增或刪除列時,無論innodb_stats_auto_recalc的值如何,都會計算索引統計資訊並將其新增到innodb_index_stats表中。

影響統計資訊的五個引數

  • innodb_stats_persistent:指定InnoDB索引統計資訊是否持久化到磁碟,預設開啟。

  • innodb_stats_persistent_sample_pages:估計索引列的基數和其他統計資訊(如由分析表計算的統計資訊)時要取樣的索引頁數。增加該值可以提高索引統計資訊的準確性,但為innodb_stats_persistent_sample_pages設定較高的值可能會導致分析表執行時間過長。

  • innodb_stats_auto_recalc:使InnoDB在表中的資料發生重大變化後自動重新計算持久統計資訊。閾值為表中行數的10%,預設開啟。

  • innodb_stats_include_delete_marked:計算持久最佳化器統計資訊時InnoDB是否包括已標記刪除的記錄,預設關閉。

  • innodb_stats_transient_sample_pages:估計索引列的基數和其他統計資訊(如由分析表計算的統計資訊)時要取樣的索引頁數。預設值為8。增加該值可以提高索引統計資訊的準確性,從而改進查詢執行計劃,但代價是在開啟InnoDB表或重新計算統計資訊時會增加I/O。該引數僅適用於為表禁用innodb_stats_persistent的情況,如果啟用了INNODB_STATS_PERSIST則應用INNODB_STATS_PERSIST_SAMPLE_PAGES代替innodb_stats_sample_pages

總結:

1、非持久化統計資訊在以下情況會被自動更新:

  1. 執行ANALYZE TABLE
  2. innodb_stats_on_metadata=ON情況下,執SHOW TABLE STATUS, SHOW INDEX, 查詢INFORMATION_SCHEMA下的TABLES, STATISTICS
  3. 啟用--auto-rehash功能情況下,使用mysql client登入
  4. 表第一次被開啟
  5. 距上一次更新統計資訊,表1/16的資料被修改

非持久化統計資訊的缺點顯而易見,資料庫重啟後如果大量表開始更新統計資訊,會對例項造成很大影響,所以目前都會使用持久化統計資訊。

2、持久化統計資訊在以下情況會被自動更新:

  1. INNODB_STATS_AUTO_RECALC=ON的情況下,表中10%的資料被修改

  2. 增加新的索引

3、統計資訊不準確的處理

我們檢視執行計劃,發現未使用正確的索引,如果是innodb_index_stats中統計資訊差別較大引起,可透過以下方式處理:

  1. 手動更新統計資訊,注意執行過程中會加讀鎖:

ANALYZETABLE TABLE_NAME;

  1. 如果更新後統計資訊仍不準確,可考慮增加表取樣的資料頁,兩種方式可以修改:

​ a. 全域性變數INNODB_STATS_PERSISTENT_SAMPLE_PAGES預設為20;

​ b. 單個表可以指定該表的取樣:

ALTER TABLE TABLE_NAME STATS_SAMPLE_PAGES=40;

​ 經測試,此處STATS_SAMPLE_PAGES的最大值是65535,超出會報錯。

​ c. 手動更新innodb_table_statsinnodb_index_stats表統計資訊(修改這兩個表不會產生binlog),然後使用FLUSH TABLE tbl_name語句載入更新後的統計資訊。


Enjoy GreatSQL 😃

關於 GreatSQL

GreatSQL是適用於金融級應用的國內自主開源資料庫,具備高效能、高可靠、高易用性、高安全等多個核心特性,可以作為MySQL或Percona Server的可選替換,用於線上生產環境,且完全免費併相容MySQL或Percona Server。

相關連結: GreatSQL社群 Gitee GitHub Bilibili

GreatSQL社群:

社群部落格有獎徵稿詳情:https://greatsql.cn/thread-100-1-1.html

image-20230105161905827

技術交流群:

微信:掃碼新增GreatSQL社群助手微信好友,傳送驗證資訊加群

image-20221030163217640

相關文章