暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL tips(六)——索引选择、字符串索引

爱可可的人生记录仪 2019-12-27
176

索引选择异常?

1.mysql如何判断一个查询的扫描行数?

选择索引是优化器的工作,扫描行数是影响的重要因素之一。通过统计信息(索引的区分度)来估算,一个索引上不同的值的个数,我们称之为“基数”(cardinality)。


2.索引基数如何计算? 通过哪个参数可以设置索引统计的存储方式?

采样统计的时候,InnoDB 默认会选择 N 个数据页,统计这些页面上的不同值,得到一个平均值,然后乘以这个索引的页面数,就得到了这个索引的基数。当变更的数据行数超过 1/M 的时候,会自动触发重新做一次索引统计。在 MySQL 中,有两种存储索引统计的方式,可以通过设置参数 innodb_stats_persistent 的值来选择:设置为 on 的时候,表示统计信息会持久化存储。这时,默认的 N 是 20,M 是 10。设置为 off 的时候,表示统计信息只存储在内存中。这时,默认的 N 是 8,M 是 16。


3.可以重新统计索引信息的命令是什么?

analyze table t 命令,可以用来重新统计索引信息。如果发现 explain 的结果预估的 rows 值跟实际情况差距比较大,可以采用这个方法来处理。但并非万能,优化器不是只看扫描行数。


4.索引选择异常的问题可以有哪几种处理方式?

采用 force index 强行选择一个索引

可以考虑修改语句,引导 MySQL 使用我们期望的索引。

在有些场景下,我们可以新建一个更合适的索引,来提供给优化器做选择,或删掉误用的索引。


如何给字符串加索引?

首先,索引选取的越长,占用的磁盘空间就越大,相同的数据页能放下的索引值就越少,搜索的效率也就会越低。所以使用前缀索引,定义好长度,就可以做到既节省空间,又不用额外增加太多的查询成本。我们在建立索引时关注的是区分度,区分度越高越好。因为区分度越高,意味着重复的键值越少。因此,我们可以通过统计索引上有多少个不同的值来判断要使用多长的前缀。但使用前缀索引就用不上覆盖索引对查询性能的优化了。


如果区分度不高怎么处理?如身份证号。

第一种方式是使用倒序存储

第二种方式是使用 hash 字段,新创建一个整数字段来保存校验码,但需要注意校验码可能存在冲突,所以where部分需要判断id的值是否精确相同。

以上两种方式都不支持范围查询,reverse函数比crc32函数消耗的cpu小一点,查询效率的话hash更好点,存储空间消耗差不多。按实际业务灵活使用。


题外话:最近效率有点低,一直在刷庆余年,下次我也要多去庙里走走,说不定遇到了我的鸡腿姑娘。切记,人外有人,语句共勉。


参考资料:丁奇,MySQL实战45讲



部分内容来自网络,如有侵权请联系作者删除。


文章转载自爱可可的人生记录仪,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论