MySQL-索引(五)

索引的目的是为了提高查询的效率,有点像字典里的部首和拼音,通过缩小范围,更快找到需要查的字,如果没有索引,你得从头到尾看一遍才能找到你要的字,效率太低了

我们前面在看数据库运行原理的时候,知道数据库落盘以后是放在磁盘里的,然后通过一些策略会把数据加载到缓存中,再通过一些策略淘汰最近不常用的数据,实际上数据保存在磁盘中,访问成本其实很高,先简单看一下磁盘io和预读机制

读取磁盘数据需要花费:(1)寻道时间,(2)旋转延迟、(3)传输时间(这三个步骤具体有兴趣可以自行去研究一下)通过三个步骤后,还需要把相邻的数据也都读取到内存缓冲中,因为局部预读性原理提到,当计算机访问到一个地址的数据时,与其相邻的数据也很快会被访问到,每次的io操作一般为一页,一般为4k或8k,而读取了一页内的数据就是发生了一次io操作,这点就是索引设计的妙处

数据结构

我们也听得很多了,索引的结构就是使用B+树,是B树的升级,增加了 通过顺序访问指针来提高区间查询的性能,我们先来了解一下什么是树

树是由有限个节点组成具有层次关系的集合,注意是层次关系,于是包含了几个特点:

(1)每个节点可以有0个或有限个子节点

(2)如果没有父节点,它为该树的根节点

(3)每个非根节点都有且仅有一个父节点,对应(2)

(4)树内部没有环路,很好理解,因为除了根节点只有一个父节点

根据节点的个数可以分为二叉树和B数

二叉树(Binary Tree):每个节点最多有两个子节点,分别称为左子节点和右子节点。
特点:简单,易于实现;查找、插入和删除操作的时间复杂度为O(logn),其中n为树中节点的数量。
区别:二叉树没有特定的平衡要求,可能出现左倾或右倾情况,导致树的高度不平衡。

平衡二叉树(Balanced Binary Tree):在二叉树的基础上,通过旋转操作保持左右子树的高度差不超过1。
特点:相比于二叉树,平衡二叉树的查询、插入和删除操作更加高效,时间复杂度为O(logn)。
区别:平衡二叉树的节点高度差不超过1,可以保证树的高度平衡。

红黑树(Red-Black Tree):一种特殊的平衡二叉树,通过节点的颜色属性来保持树的平衡。
特点:红黑树的高度近似平衡,插入、删除和查找操作的时间复杂度为O(logn)。
区别:红黑树具有更强的平衡性,通过调整节点的颜色和旋转操作来保持平衡。

AVL树:一种高度平衡的二叉搜索树,通过旋转操作保持左右子树的高度差不超过1。
特点:AVL树的平衡性更强于红黑树,查询、插入和删除操作的时间复杂度为O(logn)。
区别:相比于红黑树,AVL树的平衡性要求更严格,会导致更多的旋转操作。

B树(B-Tree):一种多路搜索树,节点可以有多个子节点。
特点:B树适用于大规模的数据存储,可以减少磁盘I/O操作,提高数据访问的效率。
区别:B树的节点可以有多个子节点,使得B树可以存储更多的键值对。

B+树(B+ Tree):在B树的基础上进行改进,只在叶子节点存储键值对。
特点:B+树适用于范围查询和顺序遍历,因为所有的叶子节点都连接成一个链表。
区别:B+树的非叶子节点只存储索引信息,而数据都存储在叶子节点上。

为什么要用B+树?

MySQL使用B+树作为索引的数据结构,主要是因为B+树具有以下几个优点:

有序性:B+树的所有数据都存储在叶子节点上,并且按照索引键的顺序排列。这种有序性使得B+树在范围查询和排序操作上具有良好的性能,可以快速定位和遍历数据。

平衡性:B+树是一种平衡的多路搜索树,它通过旋转操作来保持左右子树的高度差不超过1。这种平衡性使得B+树的查询、插入和删除操作的时间复杂度都为O(log n),其中n为树中节点的数量。

唯一性:B+树的所有节点都有一个唯一的索引键,这样可以避免重复键的问题。在查询和插入操作时,可以通过索引键快速定位到对应的叶子节点,而不需要遍历整个树。

可扩展性:B+树的节点大小固定,并且叶子节点之间通过指针连接成链表。这种固定大小和链表连接的特性使得B+树在存储和访问上具有较好的可扩展性,适合存储大规模的数据。

适合磁盘存储:B+树的节点大小通常与磁盘块大小相等,这样可以最大限度地利用磁盘的预读能力,减少磁盘I/O操作。另外,B+树的叶子节点都存储了数据记录,可以减少磁盘寻址的开销,提高数据的读取效率。

因此,B+树在有序性、平衡性、唯一性、可扩展性和适合磁盘存储等方面具有优势,能够满足数据库查询、插入和删除等操作的高效性和可靠性要求,因此成为了MySQL索引的首选数据结构。

什么是索引?

回过头来,在MySQL中,什么是索引呢?索引是一种用于加速数据库查询操作的数据结构。它是基于一个或多个列的值创建的,可以快速定位到包含特定值的数据行,而不需要全表扫描。

MySQL中常见的索引类型包括:

B-Tree索引:B-Tree(平衡树)是MySQL默认的索引类型,适用于等值查询和范围查询。它适用于大多数情况,可以通过使用多列索引来创建复合索引。

哈希索引:哈希索引适用于精确等值查询,使用哈希算法将索引列的值映射为哈希值。但是,哈希索引不支持范围查询和排序操作,并且对于哈希碰撞(多个键映射到相同的哈希值)的处理较为复杂。

全文索引:全文索引用于对文本数据进行全文搜索,支持关键词的模糊匹配和相关性排序。MySQL提供了全文索引类型,可以用于MyISAM和InnoDB存储引擎。

空间索引:空间索引适用于存储和查询地理位置数据,例如地理坐标或地理形状。MySQL支持使用R-Tree索引类型来创建空间索引。

如何使用索引:

创建索引:可以使用CREATE INDEX语句在表的一个或多个列上创建索引。例如:CREATE INDEX index_name ON table_name (column_name);

查看索引:可以使用SHOW INDEX语句来查看表中的索引信息。例如:SHOW INDEX FROM table_name;

使用索引:在查询语句中,可以通过WHERE子句使用索引来定位符合条件的数据行。例如:SELECT * FROM table_name WHERE column_name = value;

索引优化:MySQL会自动选择最佳索引来执行查询,但有时需要手动优化索引以提高性能。可以使用EXPLAIN语句来分析查询执行计划,查看是否使用了索引,以及索引的效果。

需要注意的是,索引的创建和使用需要根据具体的业务需求和查询模式进行权衡。过多或不必要的索引会增加写操作的开销和占用额外的存储空间,同时可能导致查询性能下降。因此,在设计数据库表时,需要根据实际情况选择合适的索引,并定期进行索引优化。

而优化索引的方式有很多,以下是一些常见的优化索引的方式:

(1)确保索引列选择合适:选择适合索引的列是优化索引的关键。通常,选择经常用于查询条件的列作为索引列。避免在大文本或二进制列上创建索引,因为这可能导致索引过大和性能下降。

(2)创建复合索引:复合索引是基于多个列的值创建的索引。当查询中涉及多个列时,创建复合索引可以更好地支持查询条件的匹配。但是,需要注意不要过度创建复合索引,以避免索引过大和维护开销增加。

(3)删除不必要的索引:定期检查并删除不再使用的索引,可以减少存储空间和维护开销。同时,删除过多的索引可以提高写操作的性能。

(4)避免使用MySQL不会使用的索引:MySQL在某些情况下无法使用索引,例如在函数或表达式中使用列,或者在LIKE操作中使用通配符前缀。避免这些情况下的索引使用,可以提升查询性能。

(5)使用覆盖索引:覆盖索引是指查询所需的数据都包含在索引中,不需要额外的表访问操作。通过使用覆盖索引,可以减少磁盘I/O和减少查询时间。(在mysql5.6以后的一个新特性,主要是为了减少索引的回表操作来提高数据库的查询效率,我认为最重要就是得最好覆盖索引,像一下范围查询和组合查询)

(6)统计信息更新:MySQL使用统计信息来评估查询计划并选择最佳索引。定期更新表的统计信息可以使MySQL做出更准确的查询优化决策。

(7)分析查询执行计划:使用EXPLAIN语句分析查询执行计划,了解MySQL是如何使用索引和执行查询的。通过分析查询执行计划,可以发现潜在的性能问题并进行优化。

(8)使用索引提示:在某些情况下,MySQL可能无法选择最佳索引来执行查询。可以使用索引提示(Index Hint)指示MySQL使用特定的索引执行查询,以提高查询性能。

需要根据具体的业务需求和查询模式选择合适的优化方式,并进行合理的权衡。同时,定期监控数据库性能,检查索引的使用情况,并根据实际情况进行调整和优化。

总结:

MySQL索引是一种用于提高数据库查询性能的重要工具。通过在表的列上创建索引,可以加速查询操作,减少数据的读取和匹配时间。常见的MySQL索引类型包括B-Tree索引、哈希索引、全文索引和空间索引。在使用索引时,需要选择适合的索引列、创建合适的复合索引、删除不必要的索引、避免使用MySQL无法使用的索引,以及使用覆盖索引等技巧来优化索引。同时,定期更新统计信息、分析查询执行计划和使用索引提示,可以进一步提升索引的性能。

优化MySQL索引是一个复杂而重要的任务,需要结合实际业务需求和查询模式进行权衡。以下是一些思考问题,可以帮助我们更好地理解和应用索引优化:
数据库查询模式:了解数据库中常见的查询模式是什么?哪些查询频繁执行?哪些查询对性能要求较高?
查询条件和排序规则:哪些列常用于查询条件和排序操作?是否可以通过创建索引来提高这些操作的性能?
数据库表设计:是否正确选择了主键?是否存在重复的索引?是否存在过多或不必要的索引?
数据库统计信息:是否定期更新了表的统计信息,以便MySQL做出更准确的查询优化决策?
查询执行计划:使用EXPLAIN语句分析查询执行计划,了解MySQL是如何使用索引和执行查询的,是否存在潜在的性能问题?
监控和调优:是否定期监控数据库性能,检查索引的使用情况,并根据实际情况进行调整和优化?

Leave a Reply

Your email address will not be published. Required fields are marked *