淺析MySQL的基數(shù)統(tǒng)計(jì)
一、基數(shù)是啥?
Cardinality指的就是MySQL表中某一列的不同值的數(shù)量。
如果這一類(lèi)是唯一索引,那基數(shù) = 行數(shù)。
如果這一列是sex,枚舉類(lèi)型只有男女,那它是基數(shù)就是2
Cardinality越高,列就越有成為索引的價(jià)值。MySQL執(zhí)行計(jì)劃也會(huì)基于Cardinality選擇索引。
通過(guò)下面的方式可以看到表中各列的基數(shù)。

比如這個(gè)經(jīng)典的例子:
有一列為sex,那對(duì)于sex列中存儲(chǔ)的值來(lái)說(shuō) 非男即女,它的基數(shù)最大就是2。
那也就完全沒(méi)有必要為sex建立索引。因?yàn)?,為了提升你基于sex的查詢速度,MySQL會(huì)為你選擇的這個(gè)新索引創(chuàng)建一棵全新的B+Tree。但你sex只有兩種值,對(duì)于MySQL來(lái)說(shuō),即使它為你指定的列建立了B+Tree索引,真正執(zhí)行查詢時(shí),最多進(jìn)行一次二分查詢,剩下的操作只能是遍歷,所以為sex創(chuàng)建索引意義不大。
二、InnoDB更新基數(shù)的時(shí)機(jī)?
參數(shù):innodb_stats_auto_recalc控制MySQL是否主動(dòng)重新計(jì)算這些持久性的信息。默認(rèn)為1表示true,0表示false。
默認(rèn)情況下當(dāng)表中的行變化超過(guò)10%時(shí),重新計(jì)算基數(shù)信息。
三、基數(shù)是估算出來(lái)
基數(shù)并不會(huì)實(shí)時(shí)更新!而且它是通過(guò)采樣估算出來(lái)的值!
至于基數(shù)的公式是怎樣的,可能并不重要。
重要的是你得知道,他是通過(guò)隨機(jī)采樣數(shù)據(jù)頁(yè)的方式統(tǒng)計(jì)出來(lái)的一個(gè)估算值。
而且隨機(jī)采樣的頁(yè)數(shù)可以通過(guò)參數(shù)innodb_stats_persistent_sample_pages 設(shè)置,默認(rèn)值是20。
這就意味著 基數(shù)值并不準(zhǔn)確,甚至你每次計(jì)算的結(jié)果相擦還是蠻大的。
四、持久化基數(shù)
可以通過(guò)參數(shù)innodb_stats_persistent 控制是否持久化基數(shù),默認(rèn)為off。
當(dāng)然你可以為一個(gè)單獨(dú)的表設(shè)置 STATS_PERSISTENT=1 那么它的 innodb_stats_persistent將自動(dòng)被啟用。
開(kāi)啟它的好處是:重啟MySQL不會(huì)再重復(fù)計(jì)算這個(gè)值,加快重啟速度。
五、如何主動(dòng)更新基數(shù)?
執(zhí)行下面的SQL時(shí)都會(huì)觸發(fā)InnoDB更新基數(shù)(即使你并沒(méi)有意識(shí)到它會(huì)更新基數(shù))。
所以盡量選擇一個(gè)業(yè)務(wù)低峰期
analyze table tableName;

如果因?yàn)椴蓸拥臄?shù)量太少了,計(jì)算的基數(shù)錯(cuò)的離譜。那很可能會(huì)導(dǎo)致MySQL的優(yōu)化器選錯(cuò)索引。這是你可以將這個(gè)值適當(dāng)調(diào)大。但是增加 太多可能會(huì)導(dǎo)致 ANALYZE TABLE運(yùn)行緩慢。
反之, ANALYZE TABLE運(yùn)行太慢。你可以適度調(diào)整參數(shù)innodb_stats_persistent_sample_pages 的值。但是這又可能導(dǎo)致基數(shù)計(jì)算的不準(zhǔn)確。
如果沒(méi)有辦法平衡兩者的關(guān)系??梢钥紤]減少表中索引列的數(shù)量或限制分區(qū)的數(shù)量以降低 ANALYZE TABLE復(fù)雜性。表的主鍵中的列數(shù)也很重要,因?yàn)橹麈I列被附加到每個(gè)非唯一索引中。
參考:
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
以上就是淺析MySQL的基數(shù)統(tǒng)計(jì)的詳細(xì)內(nèi)容,更多關(guān)于MySQL 基數(shù)統(tǒng)計(jì)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MySQL8.0報(bào)錯(cuò)Public?Key?Retrieval?is?not?allowed的原因及解決方法
這篇文章主要給大家介紹了MySQL8.0報(bào)錯(cuò)Public?Key?Retrieval?is?not?allowed的原因及解決方法,文中通過(guò)代碼示例和圖文介紹的非常詳細(xì),有遇到相同問(wèn)題的朋友可以參考閱讀一下2024-01-01
通過(guò)mysql show processlist 命令檢查mysql鎖的方法
show processlist 命令非常實(shí)用,有時(shí)候mysql經(jīng)常跑到50%以上或更多,就需要用這個(gè)命令看哪個(gè)sql語(yǔ)句占用資源比較多,就知道哪個(gè)網(wǎng)站的程序問(wèn)題了。2010-03-03
MySQL 虛擬列和虛擬索引的實(shí)現(xiàn)示例
在MySQL 5.7及更高版本中,虛擬列是一個(gè)非常有用的特性,本文主要介紹了MySQL 虛擬列和虛擬索引的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2025-03-03
具有負(fù)載均衡功能的MySQL服務(wù)器集群部署及實(shí)現(xiàn)
MySQL是一個(gè)高速度、高性能、多線程的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),適用平臺(tái)多,可擴(kuò)展性強(qiáng)。2011-05-05
Mysql實(shí)時(shí)備份實(shí)現(xiàn)方法
這篇文章主要介紹了Mysql實(shí)現(xiàn)實(shí)時(shí)備份,需要的朋友可以參考下2016-02-02
Mysql中大小寫(xiě)敏感問(wèn)題導(dǎo)致的MySql Error 1146 Tabel doen’t exist錯(cuò)誤
這篇文章主要介紹了Mysql中大小寫(xiě)敏感問(wèn)題導(dǎo)致的MySql Error 1146 Tabel doen’t exist錯(cuò)誤,需要的朋友可以參考下2014-10-10
關(guān)于mysql create routine 權(quán)限的一些說(shuō)明
下面小編就為大家?guī)?lái)一篇關(guān)于mysql create routine 權(quán)限的一些說(shuō)明。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03
CentOS系統(tǒng)下如何設(shè)置mysql每天自動(dòng)備份
備份是容災(zāi)的基礎(chǔ),是指為防止系統(tǒng)出現(xiàn)操作失誤或系統(tǒng)故障導(dǎo)致數(shù)據(jù)丟失,而將全部或部分?jǐn)?shù)據(jù)集合從應(yīng)用主機(jī)的硬盤(pán)或陣列復(fù)制到其它的存儲(chǔ)介質(zhì)的過(guò)程。本文將詳細(xì)介紹在CentOS系統(tǒng)下如何設(shè)置mysql每天自動(dòng)備份,有需要的朋友們下面來(lái)一起看看吧。2016-10-10

