在此之前,我做过很多ToC的项目。在ToC应用场景中,业务一般比较简单,基本没有太多复杂的查询(基本上只要创建用户ID做索引,就可以大大提高查询效率。)近两年之后,我逐渐接触了一些ToB业务,发现ToB的业务确实比ToC的业务复杂。举个简单的例子,在ToB应用中,最痛苦的就是组织架构。原本查询一个人的数据,可能会变成查询一个组、一个部门,甚至一个分支机构。不仅如此,因为不同职级的员工查询权限可能不同。查询条件比ToC场景复杂很多,所以有时候一张表会创建很多不同的索引。后来,我们会发现查询无缘无故变得很慢。按理说,如果我们打到我们想要的指标,应该很快就对了。因此,我们对Sql语句进行分析,发现Mysql使用了另外的索引,但是在这个业务中,使用另外的索引会得到更好的效果。为什么Mysql会选择错误的索引?显然,存储难我会了解业务的实际情况。Mysql也需要一定的算法来评估索引的优劣。Mysql的评分是这样的。Mysql的索引评分的首要原则是索引差异最大。比如,如果是一个小学生的信息查询系统,我们根据出生日期建一个索引,那么大概有365*7个不同的值。如果我们用学生的性别作为指标,那么基本上只有两个不同的值。如果一个查询条件同时包含出生日期和性别,那么Mysql必须优先使用基数较大的索引,即出生日期作为索引。但是,Mysql其实并不知道什么是出生日期,什么是性别,他们判断哪个基数大?很简单,扫完索引不就知道结果了吗?我们只需要扫描索引树一次,就可以知道有多少个不同的key。但是,如果我们的数据越来越多,每次都扫描所有的索引树是不现实的。基于大多数互联网应用读多写少的事实,Mysql会记录一段时间的索引分数。但是,每次触发重新评估仍然需要花费大量时间。Mysql采用抽样调查的方式,从每棵索引树中随机抽取一定数量的页面,通过统计这些页面来评价索引。现在回到我们的实际开发中,不知道大家有没有遇到过这样的问题。一些异常状态在总订单中所占的比例非常小。比如退货和退款的订单只占总订单的一小部分,但是当你用Mysql查询的时候却很好的命中了索引。是因为Mysql在打分的时候,很多时候感觉这个索引上的不同数据量很小,所以打低分。所以,如果你有这种特殊的业务场景,最好指定索引。好了,今天我们简单介绍下mysql的索引选择。不知道对你有没有启发。欢迎大家关注我,一起学习,一起进步。您的支持是我继续聊天的动力。
