索引优化方法
基本概述
MySQL中有几种索引:
主键索引(Primary Key Index):每个表都有一个主键,主键索引是自动创建的唯一索引。它通常是聚簇索引(在索引树的叶子结点中存储的是需要查找的数据)。
CREATE TABLE table_name (
id INT NOT NULL,
column1 INT,
column2 VARCHAR(255),
PRIMARY KEY (id)
);
二级索引:指除了主键索引以外的所有索引,它们可以是基于单个列(单列索引)或多个列(组合索引)的索引。二级索引在InnoDB存储引擎中被称为非聚簇索引(Non-Clustered Index),二级索引的叶子节点通常包含索引列的值和一个指向数据行的引用(在InnoDB中通常是主键的值)。
在InnoDB存储引擎中,二级索引的查询通常需要两次查找过程,称为“回表”:在索引表中记录了主键信息,找到主键后,再回表查询。
联合索引:(Composite Index,或组合索引)是在一个表的多个列上创建的索引。可以加速涉及多个列的查询。
CREATE INDEX composite_index_name ON table_name (age, name);
根据创建联合索引的顺序,以最左原则进行where检索,比如联合索引(age,name)以age=1 或 age= 1 and name=‘张三’可以使用索引,单以name=‘张三’ 不会使用索引,考虑到存储空间的问题,还请根据业务需求,将查找频繁的数据进行靠左创建索引。
覆盖索引:在这次的查询中,所要的数据已经在这棵索引树的叶子结点上了,直接返回结果,不需要进行回表,减少IO磁盘读写读取正行数据。例如查询的是主键,或者联合索引中的字段(使用最左前缀查询)。
索引下推:like 'hello%’and age >10 检索,MySQL5.6版本之前,会对匹配的数据逐个进行回表查询。5.6版本后,会先在索引中过滤掉age<10的数据,将剩下的数据再进行回表查询,减少回表率,提升检索速度
联合索引优化
建立联合索引,可以满足覆盖索引的效果,
例如身份证号是市民的唯一标识。如果有根据身份证号查询市民信息的需求,我们只要在身份证号字段上建立索引就够了。而再建立一个(身份证号、姓名)的联合索引,是不是浪费空间?如果现在有一个高频请求,要根据市民的身份证号查询他的姓名,这个联合索引就有意义了。它可以在这个高频请求上用到覆盖索引,不再需要回表查整行记录,减少语句的执行时间。
但这种索引方式为冗余索引,需要权衡实用价值与维护成本。
最左前缀:联合索引的最左 N 个字段,也可以是字符串索引的最左 M 个字符
在建立联合索引的时候,可以考虑索引的复用能力。因为可以支持最左前缀,所以当已经有了 (a,b) 这个联合索引后,一般就不需要单独在 a 上建立索引了。因此,第一原则是,如果通过调整顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的。
如果既有联合查询,又有基于 a、b 各自的询呢?查询条件里面只有 b 的语句,是无法使用 (a,b) 这个联合索引的,这时候你不得不维护另外一个索引,也就是说你需要同时维护 (a,b)、(b) 这两个索引。
然后考虑索引的空间情况,(a,b)、(b) 还是 (b,a)、(a)?这里考虑空间,字段长的只在索引中出现一次,字段短的可以建立两次索引。
作者与版本更新计划
感谢您的阅读与支持!本文是《MySQL实战与优化》专栏中的一篇精选文章,该专栏共包含16篇文章,旨在为您提供实战中可直接应用的宝贵知识。
关注公众号【数舟】,获取作者最新动态,公众号后台回复【mysql2024】,即可免费领取这份包含16篇文章的完整的PDF专栏!
目前版本为v1.0,更新时间2024年4月10日。后续此文档更新与版本发布会同步到知识星球【数舟】中。
知识整理与创作不易,感谢大家理解与支持!
加入知识星球,您将获得更多独家内容、专栏更新以及与行业内专家和同行的互动交流机会。我们在知识星球等您,一起探索MySQL的深层次世界!
星球内目前包含300+精品文章,内容涵盖大数据、MySQL、运维、Python、调优、经验分享、数据分析等方向内容,会根据大家的学习需求更新更多方向的内容。
🔗 立即扫描下方二维码,加入知识星球,与行业精英共同成长,开启您的专属学习之旅!