「談談MySQL的基數統計」

**html

Hi,你們好!我是白日夢。mysql

今天我要跟你分享的話題是:「你們常說的基數是什麼?」面試

推薦閱讀原文連接

https://mp.weixin.qq.com/s/FgxwAFQbEjv5i-TxjvLK6Qsql

這是白日夢的《爲研發同窗定製的MySQL面試指南》系列文章的第1篇文章,全書110篇文章,連載中!數據庫

全文110篇!以問答的方式,由淺入深的幫你應對各種MySQL面試題的狂轟濫炸!微信

固然也不乏會分享一些高階讀寫分離數據庫中間件原理及落地的技術實現,爲你揭開數據庫中間件神祕的面紗!優化

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

碼字不易,感謝閱讀,感謝關注,感謝在看,感謝轉發,保護!code

可加我微信 17861405320,歡迎拉你進大佬羣htm

1、基數是啥?

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

若是這一類是惟一索引,那基數 = 行數。

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

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

經過下面的方式能夠看到表中各列的基數。

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

2、InnoDB更新基數的時機?

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

3、基數是估算出來

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

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

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

並且隨機採樣的頁數能夠經過參數innodb_stats_persistent_sample_pages 設置,默認值是20。

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

4、持久化基數

能夠經過參數innodb_stats_persistent 控制是否持久化基數,默認爲off。

固然你能夠爲一個單獨的表設置 STATS_PERSISTENT=1 那麼它的 innodb_stats_persistent將自動被啓用。

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

4、如何主動更新基數?

執行下面的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

相關文章
相關標籤/搜索