索引是存储引擎用于快速找到记录的一种数据结构,这是索引的基本功能。可以把数据库的理解成一本书,而索引就是这本书的索引(每个章节在第几页),如果你知道你想查找的章节名称,就可以快速的通过索引找到这一章索引的页数,而在数据库中也类似,存储引擎会先在索引中找到对应的值(主键或者物理地址,不同的存储引擎存储的值不同),然后根据这个值找到对应的数据行。
现在可以知道索引对于查找数据的重要性,一个设计合理的索引可以很大程度的加快查询的速度,尤其在数据量很大的时候,索引对性能的影响也就更加重要了。
但是如何设计(或者优化现有)高性能索引有一些需要注意的地方:
使用自增的id作为表的主键(可以把主键理解成一个为空的唯一索引),这样做的好处是,可以保证数据按顺序写入(只在最后插入数据),如果索引不是顺序的话,在插入数据时,存储引擎要先找到需要插入的位置(可能还会进行也分裂),然后插入数据,这就增加了CPU的负载。
设计覆盖索引,覆盖索引就是索引中包含所有需要查询的字段的值,因为这样做的话可以避免数据库再回表查询,大大节约了查询效率。
选择合适的索引列顺序,如果索引中字段的顺序和查询字段的顺序不一致,会导致索引无法工作,因为索引按照最左匹配原则,即数据库会按照从左至右逐个匹配索引列。
使用索引扫描来做排序,因为当只需要从一条索引记录顺序移到下一条索引记录(但是要保证查询字段和索引字段相同,否则回回表查询索引中不包含的字段),只有当索引的列顺序和order by 子句的顺序完全一致,并且所有列的排序规则都相同时(都是正序,或者都是倒序),才能够使用索引进行排序。
避免使用多个范围查询,有范围查询的,也要把相关字段写在索引的最后,因为当匹配到第一个范围查询(id > 100 and age < 25)时,数据库不会匹配接下来的字段(只匹配到id>100)。
避免重复和冗余索引,虽然mysql允许在相同列上创建多个索引,例如(index1(name,age,sex),index2(name,age,country)),但这样mysql需要单独维护重复的索引,并且优化器在优化查询的时候也需要逐个进行考虑,这会影响查询性能。
当然不是所有的索引都需要遵循上面的规则,需要根据具体情况设计最合理的索引,没有必须遵守的规则。