談談MySQL的基數統計


**

Hi,大家好!我是白日夢。

今天我要跟你分享的話題是:“大家常說的基數是什么?”

推薦閱讀方式

首發地址:https://mp.weixin.qq.com/s/FgxwAFQbEjv5i-TxjvLK6Q

使用推薦閱讀,有更好的閱讀體驗


一、基數是啥?

Cardinality指的就是MySQL表中某一列的不同值的數量。

如果這一類是唯一索引,那基數 = 行數。

如果這一列是sex,枚舉類型只有男女,那它是基數就是2

Cardinality越高,列就越有成為索引的價值。MySQL執行計划也會基於Cardinality選擇索引。

通過下面的方式可以看到表中各列的基數。

比如這個經典的例子:
有一列為sex,那對於sex列中存儲的值來說 非男即女,它的基數最大就是2。
那也就完全沒有必要為sex建立索引。因為,為了提升你基於sex的查詢速度,MySQL會為你選擇的這個新索引創建一棵全新的B+Tree。但你sex只有兩種值,對於MySQL來說,即使它為你指定的列建立了B+Tree索引,真正執行查詢時,最多進行一次二分查詢,剩下的操作只能是遍歷,所以為sex創建索引意義不大。

二、InnoDB更新基數的時機?

參數:innodb_stats_auto_recalc控制MySQL是否主動重新計算這些持久性的信息。默認為1表示true,0表示false。
默認情況下當表中的行變化超過10%時,重新計算基數信息。

三、基數是估算出來

基數並不會實時更新!而且它是通過采樣估算出來的值!

至於基數的公式是怎樣的,可能並不重要。

重要的是你得知道,他是通過隨機采樣數據頁的方式統計出來的一個估算值。

而且隨機采樣的頁數可以通過參數innodb_stats_persistent_sample_pages 設置,默認值是20。

這就意味着 基數值並不准確,甚至你每次計算的結果相擦還是蠻大的。

四、持久化基數

可以通過參數innodb_stats_persistent 控制是否持久化基數,默認為off。

當然你可以為一個單獨的表設置 STATS_PERSISTENT=1 那么它的 innodb_stats_persistent將自動被啟用。

開啟它的好處是:重啟MySQL不會再重復計算這個值,加快重啟速度。

四、如何主動更新基數?

執行下面的SQL時都會觸發InnoDB更新基數(即使你並沒有意識到它會更新基數)。

所以盡量選擇一個業務低峰期

  • analyze table tableName;

如果因為采樣的數量太少了,計算的基數錯的離譜。那很可能會導致MySQL的優化器選錯索引。這是你可以將這個值適當調大。但是增加 太多可能會導致 ANALYZE TABLE運行緩慢。

反之, ANALYZE TABLE運行太慢。你可以適度調整參數innodb_stats_persistent_sample_pages 的值。但是這又可能導致基數計算的不准確。

如果沒有辦法平衡兩者的關系。可以考慮減少表中索引列的數量或限制分區的數量以降低 ANALYZE TABLE復雜性。表的主鍵中的列數也很重要,因為主鍵列被附加到每個非唯一索引中。

參考:

https://dev.mysql.com/doc/refman/5.7/en/innodb-persistent-stats.html

https://dev.mysql.com/doc/refman/5.7/en/innodb-analyze-table-complexity.html


推薦閱讀

  1. 大家常說的基數是什么?(已發布)
  2. 講講什么是慢查!如何監控?如何排查?(已發布)
  3. 對NotNull字段插入Null值有啥現象?(已發布)
  4. 能談談 date、datetime、time、timestamp、year的區別嗎?(已發布)
  5. 了解數據庫的查詢緩存和BufferPool嗎?談談看!(已發布)
  6. 你知道數據庫緩沖池中的LRU-List嗎?(已發布)
  7. 談談數據庫緩沖池中的Free-List?(已發布)
  8. 談談數據庫緩沖池中的Flush-List?(已發布)
  9. 了解臟頁刷回磁盤的時機嗎?(已發布)
  10. 用十一張圖講清楚,當你CRUD時BufferPool中發生了什么!以及BufferPool的優化!(已發布)
  11. 聽說過表空間沒?什么是表空間?什么是數據表?(已發布)
  12. 談談MySQL的:數據區、數據段、數據頁、數據頁究竟長什么樣?了解數據頁分裂嗎?談談看!(已發布)
  13. 談談MySQL的行記錄是什么?長啥樣?(已發布)
  14. 了解MySQL的行溢出機制嗎?(已發布)
  15. 說說fsync這個系統調用吧! (已發布)
  16. 簡述undo log、truncate、以及undo log如何幫你回滾事物! (已發布)
  17. 我勸!這位年輕人不講MVCC,耗子尾汁! (已發布)
  18. MySQL的崩潰恢復到底是怎么回事? (已發布)
  19. MySQL的binlog有啥用?誰寫的?在哪里?怎么配置 (已發布)
  20. MySQL的bin log的寫入機制 (已發布)


面試官都關注了!你還在猶豫什么呢?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM