很多人背最左匹配背得滚瓜烂熟,上来就建联合索引,比如(a,b,c),觉得能覆盖各种组合查询。但很少有人想,这个索引的字段顺序到底是按什么排的?如果把低基数的字段放在最左,比如性别、是否删除这种只有两三个值的字段,那这个索引的区分度极低,查出来还是几万行数据,跟全表扫描差不了多少,完全白建。
还有人不知道最左匹配的边界条件,如果查询里在中间的字段用了范围查询,后面的字段就用不上索引了。比如where a=1 and b>10 and c=2,那c这个字段的索引就直接失效了,等于你白加了c的字段在联合索引里,平白占了存储,还增加了写入的维护成本。
还有人迷信覆盖索引,觉得把所有查询要的字段都塞到索引里,就能不用回表,速度最快。但很少有人算过,如果索引塞的字段太多,索引树的节点会变得特别宽,同样的内存页能存的节点数就变少,树的层级可能从3层涨到4层,查询一次要多一次IO,反而更慢。
后来那个做电商的工程师把多余的三个普通索引删了,换成了一个刚好覆盖运营筛选需求的联合索引,压测的时候写入QPS回到了原来的水平,查询延迟也没涨多少。
数据库索引从来不是越多越好。也不是越复杂越好。每次加索引之前,先算清楚账。你要的是整个系统的整体性能最优,不是某一个查询的速度变快。