1. 索引的介绍
索引是一种用于快速查询和检索数据的数据结构,其本质可以看作是一种排序好的数据结构。
索引底层数据结构有很多类型,常见的索引结构有:B树、B+树、Hash和红黑树。在MySQL中,无论是Innodb还是MyISAM,都使用了B+树作为索引结构。
优点:使用索引可以很大程度上加速数据检索的速度,减少I/O次数。
缺点:维护索引需要耗费资源,当对表中的数据进行增删改的话,如果数据有索引,那么对应的索引也需要动态的修改。并且索引也需要占用一定的存储空间
‼️:索引不一定能够提高查询性能,如果数据量不大的情况下,使用索引有时候还不如直接全表扫描来得快。
2. 索引底层的数据结构
B+Tree:无论是 InnoDB 引擎还是 MyISAM 引擎都是使用 B+Tree 作为索引的结构,因为其支持范围查询和顺序查询,且相比于 B树 具有更稳定的查询效率和更少的 I/O 次数。
InnoDB和MyISAM中B+树的不同:
InnoDB 中主索引的叶子节点是会存储完整的记录信息的,所以 InnoDB 表数据本身就是主索引,其余索引都被称为辅助索引,他们的叶子节点不存储完整的记录信息,只存储
key
和主键的值,因此一般情况下,使用辅助索引进行查询需要进行回表操作,也就是会回到主索引中查询完整的数据(当然覆盖索引除外)MyISAM中,B+Tree 的叶节点的
data
域存储的是记录的地址,所以相比于 InnoDB ,MyISAM 的 I/O 次数会相对较多。
3. 索引类型:
主键索引:列值唯一,且不能为null,可以加速查询
唯一索引:列值唯一,可以为null,也可以加速查询
覆盖索引:一个索引包含要查询的所有字段,也就是我们的查询内容和条件都在覆盖索引的字段中,那么使用覆盖索引:可以直接获取到所需的所有数据,可以防止回表,加快查询速度。
普通索引:可以加速查询
全文索引:对文本内容进行分词,然后搜索,只
varchar
chartext
列上可以创建,但是一般不会用,该功能一般用搜索引擎嗲提,ElasticSearch
。前缀索引:对文本的前几个字符创建索引,相比普通索引建立的数据更小,因为只取前几个字符。
联合索引:多个列构成一个索引,专门用于组合搜索,其效率大于索引合并(但是会有最左前缀问题)
最左前缀匹配原则:使用联合索引时,MySQL 会根据索引中的字段顺序,从左到右一次匹配查询条件中的字段,如果查询条件与索引中的最左侧字段相匹配,那么MySQL就会使用索引来过滤数据,这样可以提高查询数据。当碰>、<
时,会停止匹配(当前条件可以用上),但是碰 >= 、<= 、between、like
的时候,不会停止匹配,联合索引依旧可以用到。
索引下推(Index Condition Pushdown,ICP):它允许存储引擎在索引遍历过程中,执行部分 where
语句的判断条件(索引失效时,使用判断条件先过滤掉一些肯定不满足的数据),直接过滤掉不满足条件的记录,从而减少回表的次数
4. 使用索引的建议
选择合适的字段创建:
不为 null 的字段:对于数据为 null 的字段,数据库比较难优化,如果字段频繁查询,但是又避免不了为null,建议使
0/1、true/false
这样语义较为清晰的短值或短字符作为替代。where子句中的列:为频繁出现在
where
条件中的列创建索引,尤其是筛选数据比例较小的列连接
join
:为表连接的列创建索引,加速关联查询。高选择性的列:选择区分度高的列(如唯一ID、用户账号等)。
排序和分组列:为尝出现在
order by
和group by
中的列创建索引,避免额外的排序操作频繁更新的列,应该尽量不设置索引
限制每张表上的索引数量,单张表索引尽量不超过5个,维护太多索引的会降低数据更新的效率。
尽量尽力联合索引,而不是单列索引,首先,每个索引都会占用一定的磁盘空间,也就是每个索引代表一颗 B+Tree,建立联合索引可以节约很大的磁盘空间,并且更新数据的操作效率也会提升。
避免冗余索引,也就是,联合索引(a,b),可以命中,那么索引a,也就可以命中。
避免索引失效:
隐式类型转换:比如字符串列用数字查询
where str=111
会导致索引失效函数或表达式:
where YEAR(date_col)=2025
无法使用索引,需改写为范围查询前导通配符:
LIKE '%abc'
无法使用索引,LIKE 'abc%'
可以。or
条件不当:若or
两侧的列均有索引,可能触发索引合并,否则可能全表扫描。
评论区