既然我们已经对索引的本质有所了解,那么我们就应该来讨论如何高性能的使用引擎。
1. 列的离散性越高,选择性越好。
列的离散性是这样定义的:count(discount col):count(col),也就是不同的列数比列的总数。这个数值越大说明列的离散型就越好。
如果用离散性很低的列,比如性别来做索引,你会发现大家都只有两种值(男和女),这样其实你根本不知道应该往那条路走,区别度太低,选择性很差。相反离散性越高的选择性就越好。
就仿佛你喊男的会有50个男的回头,你喊李二狗就只有李二狗回头一样。
2. 最左匹配原则
对索引中关键字进行的匹配,一定是从左往右依次进行的,且不可跳过。
这也就是我们常常说的,不要用like %这种写法,左边写%会让索引失效(字符串就是用ASCII码进行比较,数据库可以选择比较方式比如是否区分大小写)。
3. 联合索引使用原则
联合索引其实就是有好多关键字的索引(但是关键字之间不是拼接,按照有分隔符把他分开来理解),单列索引这么看来就是一种特殊的联合索引。
总的来说一下联合索引的使用原则吧:
1. 经常使用的列优先(最左匹配原则)
2. 选择性高(离散性高)的列优先(离散度高原则)
3. 宽度小的列优先(最少空间原则)
我们来理解一下,因为从上面提到的最左匹配原则来看,我们肯定是最先匹配最左边的列,所以最常用的列放在最左边可以提高索引的覆盖范围。(仅对索引,查询条件数据库会重新组合不需要在意顺序)
而选择性高的列能帮助我们尽快的把数据区分开,这上面也说过了是离散度高原则。
宽度小的列优先,可以节省空间。
4. 覆盖索引
如果查询列可以通过索引节点中的关键字直接返回,则该索引称之为覆盖索引。
因为从我们的b+模型中可以看出,我们把所有关键字的数据信息都留在了叶子节点,但关键字本身是保存在非叶节点上的。也可就是说如果我们保存在非叶节点上的关键字已经可以覆盖这次返回所需的所有字段,我们就可以直接命中返回,不需要往下查叶子节点了,这样的好处是很明显的。
覆盖索引可以减少数据库IO,将随机IO变为顺序IO,可提高查询性能。