“谈谈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

相关文章
相关标签/搜索