最近面试碰到最多的问题就是数据库优化,准备一步一步整理一下数据库优化的方式
一、mysql 中索引的实现方式
想要优化索引就需要了解索引的数据结构,或者说是实现方式。
索引的实现方式非常多,今天我们主要讨论以下两种。
1.Hash 表索引
Hash 表是先将原数据按照 Hash 函数运算之后得到 HashCode,再按 HashCode 进行排序后组成的表。
但是,Hash 表的长度是固定且有限的,在数据库索引的应用中很可能得到相同的 Hash 值。这个时候我们就需要通过 Hash 表+链表的方式来存储相同 HashCode 的数据。这时 Hash 表的查询操作的时间复杂度为 O(n)。
虽然我们可以使用其他方式来降低这个这个时间复杂度 ( 这在我之前数据结构|Hash表的文章中也讨论过)。 但是这也必须付出空间的代价,因此 MySQL 索引使用了 B+ 树,而没有使用散列表。
2.B 树索引
B 树是非二叉树。
B 树的每个非叶子结点可以拥有多个子节点,我们可以把它理解为 m 叉树。这样做的好处就是可以降低树的高度(减少磁盘 I/O 次数)。
MySQL 索引使用的 B+ 树就是 B 树改进后的产物。与 B 树相比,B+ 树的节点并不存储数据,节省了空间。同时,B+ 树还使用了双向链表链接每个叶子结点,提升了效率。
了解了实现方式,我们就能分析出数据库的适用场景。也能考虑优化策略。
二、索引优化的思路
1.尽量使用主键索引查询
使用普通索引进行查询时,在查询到对应的 q
基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询。
2.主键尽量使用自增
在适宜的情况下,将主键设置为 AUTO_INCREMENT 自增列(比如用户 id)。
之后每次插入一条记录,不需要挪动其他的记录。 同时,还能减少占用空间 ( 不会出现页分裂 )。
3.使用覆盖索引
mysql 可以通过索引来直接获取数据,这样就不需要读取数据行,也就不需要回表的操作了。
比如我们查询 user ,id 两个值,而索引中已经包含了这两个值,那就不需要进行回表操作了。
如果一个索引能涵盖常用的查询字段,这种索引就是覆盖索引。
使用覆盖索引可以减少数据的访问量,索引占用的内存也比数据小,可以全部放入内存中。
不过,覆盖索引需要存储索引列值,因此像 Hash 索引这样不存储列值的索引就无法使用覆盖索引了(这也是主流数据库选择 B 树索引的重要原因)。
4.较长的字符串选择前/后缀索引
数据库中经常有较长的字符串,选择合适的前/后缀来创建索引可以减少索引占用的空间提升查询效率。
前缀索引使用的问题我们在另一篇文章《前缀索引有什么用?》,中有更深入的讲解。
评论区