在mysql中,索引是存储引擎用于快速查找到目标记录的一种数据结构。常见的索引类型包含B树索引、哈希索引、空间索引(R-Tree)、全文索引等。
索引是在存储引擎层实现的,不同的存储引擎对索引的工作方式并不一样。
下面重点介绍B树索引以及innodb和myisam存储引擎。
选择B树的原因
读写磁盘代价最高的环节是寻道,按照顺序访问范围数据是很快的,这有两个原因:
- 顺序I/O不需要多次寻道,所以比随机I/O要快很多(特别是对于机械硬盘)。
- 如果服务器能够按需要顺序读取数据,那么就不需要额外的排序操作,并且goup by查询无需再做排序和将行按组进聚合计算了。
索引本身可能很大,不能全部放在内存,因此往往以索引文件的形式存储的磁盘上。这样一来,索引查找过程中就要产生磁盘I/O消耗。相对于内存存取,I/O存取的消耗要高几个数量级,设计索引时,其结构组织要尽量减少查找过程中磁盘I/O的存取次数。
B树是与红黑树类似的一颗平衡查找树,但在降低磁盘I/O操作次数方面更好一些,B树具有较低的深度,查找一个元素只需将很少节点从磁盘Load到内存,很快便能访问到要查找的数据。
B树介绍
一棵B树T是具有如下性质的有根树(根为root[T]):
- 每个节点x有以下域:
- 每个内节点x包含x.n+1个指向其子女的指针,叶节点没有子女,故他们子女的指针域无定义。
-
如果ki为存储在节点x子节点内的关键字则:
-
每个叶节点具有相同的深度,即树的高度h
- 每个节点所包含的关键字个数x.n包含一个上界和下界,用一个固定的整数t>=2来表式;
- 每个非根的节点至少包含t-1个关键字。每个非根的内节点至少有t个子女,如果树是非空的,则根节点至少包含一个关键字。
- 每个节点至多包含2t-1个关键字,所以说一个内节点至少包含2t个子女,我们说一个节点是满的,如果这个节点恰好包含2t-1个关键字。
B+树
B+树是B树的一个变种,B+树比B树更适合实现外存储索引结构,MySQL存储引擎普遍使用B+Tree实现其索引结构。内节点只包含键值以及指向子节点的指针,数据存储在叶子节点,所有记录节点都是按照键值的大小顺序存放在同一层的叶节点中,各节点指针进行连接(双向链表)。
如图:所有记录都在叶节点中,井且是顺序存放的,如果我们从最左边的
叶节点开始顺序遍历,可以得到所有镗值的顺序排序15、10、15、20、25、30、50、55、60、 65、 75、 80、 85、 90
B+树内节点和叶节点的大小可以是不同的。
索引实现
存储引擎以不同的方式使用B+树,索引列是按照顺序组织的。B+树索引在数据库中有一个特点就是其高扇出性,因此数据库中B+树的高度一般都在2~3层,也就是说对于查找某一键值的行记录,最多只需要2到3次IO。
B+树索引
数据库中B+树索引可以分为聚集索引(clustered index)和辅助聚集索引(secondary index),但不管是聚集还是非聚集的索引,其内部都是B+树的,即高度平衡的,叶节点存放着所有的数据。
聚集索引与非聚集索引不同的是,叶节点存放的是否是一整行的信息。
来看看InnodDB和MyISAM是如何存储下面这张表的:
1 2 3 4 5 6 |
Create Table layout_test( col1 int not null, col2 int not null, primary key(col1), key(col2) -- 二级索引 ) |
MyISAM引擎使用B+Tree作为索引结构,索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。叶节点每个项的数据域存放的是记录的地址,记录写入时按照插入的顺序存储在磁盘上。
MyISAM中主键索引和其它索引在结构上面没有什么不同,主键索引就是一个名为Primary的唯一非空索引。
而在InnoDB中,主键就是聚集索引,表数据文件本身就是按B+Tree组织的一个索引结构,叶子节点包含了主键和行的全部数据,内节点页只包含了索引列主键。聚集索引中键值的逻辑顺序决定了表中相应行的物理顺序。InnoDB二级索引的叶子节点中存储的不是“行指针”,而是主键值,并以此作为指向行的“指针”,可知聚集索引就是按照表的主键构造的一棵B+树。
聚集索引的叶节点的每一个项包含了主键、事务ID、用于事务和MVCC的回滚指针以及所有的剩余列。
InnoDB的二级索引和聚集索引很不相同。InnoDB二级索引的叶子节点存储的不是“行指针”,而是主键值,并以此作为指向“行的指针”。这样的策略减少了当前行移动或者数据页分裂时二级索引的维护工作。使用主键值当做索引指针会让二级索引占用更多的空间,换来的好处是,InnoDB在移动时无需更新二级索引中的这个“指针”。
从下图比较容易看出InnoDB和MyISAM保存数据和索引的区别。
聚集索引的优点
聚集索引的存储井不是物理上的连续,相反是逻辑上连续的,页内是连续的,页间通过双向链表链接。
聚集索引的另一十好处是,它对于主键的排序查找和范国查找速度非常快。
innodb的逻辑存储结构, 从InnoDB存储引擎的逻辑存储结构看,所有数据都被逻辑地存放在一个空间中,称之为表空间(tablespace)。表空间又由段(segment)、区(extent)、页(page)组成。页在一些文档中有时也称为(block),InnoDB存储引擎的逻辑存储结构大致如图:
- 可以把相关数据保存在一起,尤其是访问的数据聚集在一个页上,可以减少io次数;
- 数据访问更快。聚族索引将索引和数据保存在同一个B树中,因此从聚族索引中获取数据通常比在非聚族索引中查找更快。
- 使用覆盖索引扫描的查询可以直接使用节点中的主键值。
聚集索引的缺点
- 聚集数据最大限度的提高了I/O密集型应用的性能,但如果数据全部都放在内存中,则访问的顺序就没有那么重要了,聚集索引也就没有那么优势了;
- 插入速度严重依赖于插入顺序。按照主键的顺序插入是加载数据到InnoDB表中速度最快的方式。但如果不是按照主键顺序加载数据,那么在加载完成后最好使用OPTIMIZE TABLE命令重新组织一下表。
- 更新聚集索引列的代价很高,因为会强制InnoDB将每个被更新的行移动到新的位置。
- 基于聚集索引的表在插入新行,或者主键被更新导致需要移动行的时候,可能面临“页分裂”的问题。当行的主键值要求必须将这一行插入到某个已满的页中时,存储引擎会将该页分裂成两个页面来容纳该行,这就是一次分裂操作。页分裂会导致表占用更多的磁盘空间。
- 聚集索引可能导致全表扫描变慢,尤其是行比较稀疏,或者由于页分裂导致数据存储不连续的时候。
- 二级索引(非聚集索引)可能比想象的要更大,因为在二级索引的叶子节点包含了引用行的主键列。
- 二级索引访问需要两次索引查找,而不是一次。
参考:
相关推荐
总之,MySQL索引的原理在于利用各种数据结构,如有序数组、链表和B+Tree,来优化数据检索过程,尤其是在大数据量的场景下。了解这些原理有助于我们在设计数据库时做出明智的决策,合理使用索引,以提升系统的整体...
MySQL 索引机制详细解析 MySQL 索引机制是 MySQL 中的一种数据结构,它可以加快数据的检索速度。索引机制是指在数据库中的每一列上建立的数据结构,是一种快速查找和定位数据的方法。 一、索引的类型 MySQL 索引...
MySQL索引介绍学习 MySQL索引是一种数据结构,用于帮助MySQL高效获取数据。索引的本质是一种排序的数据结构,可以快速查找数据。MySQL官方定义:索引(Index)是帮助MySQL高效获取数据的数据结构。 索引存在于哪里...
本文将深入探讨Oracle与MySQL在索引管理方面的差异,包括索引类型、创建与管理索引的语法,以及索引优化的策略,并提供详细的代码示例。 Oracle与MySQL在索引管理方面各有特点。Oracle提供了更复杂的索引类型和维护...
### MySQL索引分析和优化深度解析 #### 引言 MySQL数据库系统中,索引扮演着至关重要的角色,尤其在大数据量的环境下,其对查询性能的影响不可小觑。索引能够极大地加速数据检索速度,减少数据库服务器的负载,...
MySQL配置文件解析主要涉及到MySQL服务器的参数调整,这些参数直接影响数据库的性能和稳定性。配置文件通常命名为`my.cnf`或`my.ini`,在不同的操作系统路径可能不同。以下是几个关键参数的解释: 1. `port`:指定...
本篇文章将全面解析MySQL索引的所有关键知识点。 首先,我们需要理解索引的基本概念。在MySQL中,索引是一种数据结构,用于加速对表中数据的访问。它们存储在单独的物理结构中,允许数据库系统快速定位到数据行。...
本文通过对MySQL索引的基础概念介绍,结合Index Condition Pushdown的深入解析,帮助读者更好地理解了联合索引的使用方式以及ICP如何优化多列索引查询。通过实际的实验案例,展示了ICP带来的性能提升效果。这对于...
而B+tree是B-tree的一个变种,大名鼎鼎的MySQL就普遍使用B+tree实现其索引结构。那数据库为什么使用这种结构?一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样...
面试时,交流有关mysql索引问题时,发现有些人能够涛涛不绝的说出B+树和B树,平衡二叉树的区别,却说不出B+树和hash索引的区别。这种一看就知道是死记硬背,没有理解索引的本质。本文旨在剖析这背后的原理,欢迎留言...
MySQL索引原理查找算法:二叉查找树BitMap位图索引分类主键索引唯一索引普通索引全文索引索引原理解析B+树聚集索引和非聚集索引建立索引创建表时指定组合索引
### MySQL之Linux安装与索引优化笔记 #### 一、MySQL简介及Linux版安装 **1. MySQL概述** MySQL是一种关系型数据库管理系统(RDBMS),由瑞典MySQL AB公司开发,目前属于Oracle公司。它是一种开源软件,因其性能...
### MySQL索引及性能优化知识点解析 #### 一、MySQL性能下降的表现与原因 1. **性能下降的表现**: - 执行时间显著延长。 - 用户操作等待时间增加。 - 查询响应时间不稳定。 2. **性能下降的原因**: - **...
在这个“日志文件解析MySQL版”的资源包中,提供了JAVA源代码、可执行jar文件、日志文件样例以及MySQL建表脚本,这将帮助我们构建一个完整的日志分析系统,以下将详细介绍其中涉及的知识点。 首先,**JAVA日志解析*...
MySQL索引长度限制是数据库设计中的一个重要因素,它直接影响到数据检索的速度和存储空间的效率。在MySQL中,不同的存储引擎对索引长度有不同的限制,这主要是由它们的内部实现和设计目标决定的。 首先,InnoDB引擎...
MySQL支持主键、外键、唯一和非空约束,对检查约束仅做解析但不强制执行。PostgreSQL在此基础上增加了检查约束的强制执行,且其存储过程和用户定义函数可通过多种编程语言实现,如PL/pgSQL、Tcl、Perl、Python和C。 ...
MySQL索引的深入解析 MySQL索引是一种数据库结构,用于加快数据检索速度。它们通过预排序数据并提供指向数据行的直接指针来减少数据库查询的执行时间。索引的选择和设计对于数据库性能至关重要,尤其是在大数据量的...