MySQL:索引(Index)理论知识

打印 上一主题 下一主题

主题 1043|帖子 1043|积分 3129

关系型数据库中,索引(Index)是一种用于加快数据检索速度的数据布局。它通过存储某些列的值的指针,来提高查询的效率
一样平常环境下,索引是在表中的一个或多个列上创建的,它们可以显著提高查询的效率。
当我们使用 SELECT 语句查询一个表时,假如没有索引,数据库需要扫描每一行数据,这会花费大量时间,特殊是对于大型的数据集。假如有了索引,数据库就可以用更快的方式定位到需要的数据行,由于它可以使用索引中存储的值来快速查找匹配的行。
索引的优缺点

优点



  • 索引大大减小了服务器需要扫描的数据量,从而大大加快数据的检索速度,这也是创建索引的最重要的缘故原由。
  • 索引可以帮助服务器制止排序和创建暂时表
  • 索引可以将随机 IO 酿成顺序 IO
  • 索引对于 InnoDB(对索引支持行级锁)非常重要,由于它可以让查询锁更少的元组,提高了表访问并发性
  • InnoDB 在二级索引上使用共享锁(读锁),但访问主键索引需要排他锁(写锁)
  • 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
  • 可以加速表和表之间的毗连,特殊是在实现数据的参考完备性方面特殊有意义。
  • 在使用分组和排序子句举行数据检索时,同样可以显著减少查询中分组和排序的时间。
  • 通过使用索引,可以在查询的过程中,使用优化隐蔽器,提高系统的性能。
缺点

虽然索引可以显著提高查询的效率,但也会增长写入操纵的开销。由于每次写入操纵都需要更新索引,这大概导致写入操纵比没有索引的环境下慢一些。因此,在创建索引时需要权衡查询效率和写入效率之间的权衡。


  • 创建索引和维护索引要耗费时间,这种时间随着数据量的增长而增长
  • 索引需要占用物理空间,除了数据表占用数据空间之外,每一个索引还要占用肯定的物理空间,假如需要建立聚簇索引,那么需要占用的空间会更大
  • 对表中的数据举行增、删、改的时候,索引也要动态的维护,这就降低了整数的维护速度
  • 假如某个数据列包罗很多重复的内容,为它建立索引就没有太大的现实效果。
  • 对于非常小的表,大部分环境下简朴的全表扫描更高效;
创建索引的准则

索引是建立在数据库表中的某些列的上面。因此,在创建索引的时候,应该过细考虑在哪些列上可以创建索引,在哪些列上不能创建索引。
需要创建索引的列



  • 在常常需要搜索的列上,可以加快搜索的速度
  • 在作为主键的列上,逼迫该列的唯一性和构造表中数据的分列布局
  • 在常常用在毗连(JOIN)的列上,这些列重要是一些外键,可以加快毗连的速度
  • 在常常需要根据范围(<,<=,=,>,>=,BETWEEN,IN)举行搜索的列上创建索引,由于索引已经排序,其指定的范围是连续的
  • 在常常需要排序(order by)的列上创建索引,由于索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
  • 在常常使用在 WHERE 子句中的列上面创建索引,加快条件的判断速度。
无需创建索引的列



  • 对于那些在查询中很少使用或者参考的列不应该创建索引
    若列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增长了索引,反而降低了系统的维护速度和增大了空间需求。
  • 对于那些只有很少数据值或者重复值多的列也不应该增长索引。
    这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增长索引,并不能明显加快检索速度。
  • 对于那些定义为 TEXT, IMAGE 和 BIT 数据范例的列不应该增长索引。这些列的数据量要么相当大,要么取值很少。
  • 当该列修改性能要求远远高于检索性能时,不应该创建索引。(修改性能和检索性能是互相矛盾的)
索引分类

MySQL 的索引有两种分类方式:逻辑分类物理分类
逻辑分类

按逻辑分类有多种逻辑分别的方式,如按功能分别,按组成索引的列数分别等。
按列数分别

单例索引

单例索引:在数据库中为单个列创建的索引。一个索引只包罗一个列,一个表可以有多个单例索引。
单例索引的特点和用途包括:

  • 提高查询性能:通过为单个列创建索引,可以加快根据该列举行的搜索和排序操纵的速度。当查询条件涉及到单个列时,单例索引可以显著提高查询性能。
  • 索引大小较小:相比于多列索引,单例索引只涉及一个列,因此索引本身的大小往往较小。这可以减少索引的存储空间占用,并提高索引的缓存效率。
  • 准确匹配本领:单例索引适用于需要举行准确匹配的查询,例如等值查询。通过单例索引,可以快速定位到符合查询条件的记录。
  • 不适用范围查询:由于单例索引只包罗一个列的索引信息,所以对于范围查询(如大于、小于等)的效果并不抱负。范围查询大概需要扫描更多的索引页,导致查询性能下降。
使用单例索引时需要权衡索引的选择,由于过多地创建索引大概会造成存储空间的浪费和性能的下降。
组合索引(多列索引)

组合索引:一个组合索引包罗两个或两个以上的列。查询的时候遵循 MySQL 组合索引的 “最左前缀”原则,即使用 WHERE 时条件要按照建立索引的时候字段的分列方式放置索引才会生效
组合索引的重要特点和用途包括:

  • 支持复合查询:组合索引可以为复合查询提供支持,即基于多个列举行查询和排序操纵。例如,可以根据 用户ID 和 影戏评分 两个列举行查询,以找到用户评分最高的影戏列表。
  • 提高查询性能:针对复合查询,可以通过创建组合索引来提高查询性能。由于该索引涉及多列数据,因此可以在多个列之间建立更紧凑、更高效的数据布局,减少扫描数据的次数。
  • 减少索引数目:相对于每个列都创建单独的索引,组合索引可以减少所需索引的数目,并减少索引维护的成本,提高查询性能。
  • 顺序匹配:组合索引会按照指定的列顺序存储数据,因此只有使用索引的前缀列时,查询才能够利用到索引。例如,假如索引顺序是(用户ID,影戏评分),那么只有查询时涉及到 用户ID 列时,才能够利用索引举行匹配。
按功能分别

主键索引

主键索引:针对主键列(PRIMARY KEY)建立的索引,保证主键的唯一性和查询效率。一张表只能有一个主键索引,不允许重复、不允许为 NULL
其优点是方便高效地查找数据并确保数据的唯一性,由于数据库会对主键自动建立索引。主键索引适用于对表举行快速查询、排序、合并等操纵。
唯一索引

唯一索引:针对唯一性列(UNIQUE)建立的索引,同样保证列的唯一性和查询效率。数据列不允许重复,允许为 NULL 值,一张表可有多个唯一索引,索引列的值必须唯一,但允许有空值。假如是组合索引,则列值的组合必须唯一。
和主键索引相比,唯一索引并不自动成为主键。唯一索引适用于需要保证某个列的数据唯一性而不需要建立主键的环境。
普通索引

普通索引:普通索引也称为非唯一索引,用于提高查询效率。一张表可以创建多个普通索引,一个普通索引可以包罗多个字段,允许数据重复,允许 NULL 值插入
普通索引不要求列的数据唯一性。使用普通索引可以加快查询速度,但需要权衡建立索引所带来的开销和维护索引所需的时间,由于索引可以占用较大的数据库存储空间。
全文索引

全文索引:全文索引用于对文本范例的数据举行搜索
这种索引可以在文本列中匹配单词等细节性内容,而不但仅是与整个文本比较。全文索引适用于需要对文本范例数据举行全面搜索和匹配的场景,如博客、论坛和搜索引擎等。
全文索引的重要特点和用途包括:

  • 文本搜索本领:全文索引可以处置处罚文本数据中的字词、短语和自然语言查询,而不但仅是简朴的单词匹配。它支持模糊搜索、通配符搜索、拼写纠错和同义词扩展等功能。
  • 搜索效率提升:通过使用全文索引,可以大大提高对大量文本数据举行搜索操纵的效率。相对于传统的基于模式匹配的搜索方法,全文索引可以更快地找到匹配的结果。
  • 支持多语言:全文索引技术可以应用于差别语言的文本数据,并提供对多语言搜索的支持。它可以处置处罚差别的字符集、词法和语法规则等。
  • 排序和权重:全文索引可以对搜索结果举行排序和打分,以便更好地匹配用户的查询意图。它可以根据搜索词的出现频率、位置和关联性等因素为结果赋予权重。
  • 高级搜索功能:全文索引还支持高级搜索功能,如范围搜索、逻辑运算符(与、或、非)的组合以及近似搜索等。这些功能可以进一步提升搜索的精度和灵活性。
空间索引 SPTIAL

空间索引(Spatial Index)是一种用于加速地理空间数据查询的数据布局。它重要用于管理和优化在二维或三维空间中存储的地理空间数据,如点、线、面等。
传统的索引布局,好比B树或哈希索引,无法直策应用于地理空间数据的查询,由于这些数据具有差别的特点:位置相干性、多维性和范围查询等需求。而空间索引就是为了满意这些特点而计划的。
常见的空间索引布局包括:

  • R树(R-tree):R树 是一种多维索引布局,被广泛应用于空间数据的管理。它可以用于范围查询、最近邻查询、相交查询等地理空间查询。R树可以将地理空间数据构造成一个树形布局,通过节点间的相互关系,减少不须要的搜索和访问。
  • Quadtree:Quadtree 是一种基于四叉树的空间索引布局。它将空间分别为四个象限,每个象限又分别成四个子象限,以此类推,直到分别到某一条件满意为止。Quadtree重要用于场景的近似匹配查询,好比找到与一个给定区域相交的数据。
  • KD-tree:KD-tree 是一种二叉树布局,用于高维空间数据的索引。它将空间按照垂直切割的方式构建树布局,每个节点存储一个数据点,并根据数据点的位置在空间中举行切割。KD-tree重要用于最近邻查询和范围查询。
除了以上几种常见的空间索引布局,还有很多其他的索引布局,如 R+Tree、Hilbert R树 等。选择合适的空间索引布局要考虑数据的特征、查询需求和系统性能等方面的因素。
物理分类

按照物理分类,索引可以分为聚簇索引(也称主索引)和非聚簇索引(也称辅助索引或二级索引)
聚簇索引(主索引)

聚簇索引(Clustered Index)是一种特殊的数据库索引,它是根据表的某一列(聚簇键)的数据顺序建立的,而不是像普通索引那样是按索引列分列数据。
聚簇索引不是单独的一种索引范例,而是一种数据存储方式。这种存储方式是依赖 B+Tree 来实现的,根据表的主键构造一棵 B+树 且 B+树 叶子节点存放的都是表的行记录数据时,方可称该主键索引为聚簇索引。也可明白为将数据存储与索引放到了一块,找到索引也就找到了数据。
聚簇索引的优势在于,数据的物理存储顺序和聚簇索引的排序顺序是同等的,即相邻的记录在物理上也是相邻的,这样可以最大程度地提高查询效率,尤其对于主键的排序查找和范围查找速度非常快,大大减少磁盘 I/O 操纵。
聚簇

聚簇是为了提高某个属性(或属性组)的查询速度,把这个或这些属性(称为聚簇码)上具有相同值的元组集中存放在连续的物理块。
当通过聚簇码举行访问毗连是该关系的重要应用,与聚簇码无关的其他访问很少或者是次要的,这时可以使用聚簇。
建立聚簇

一个数据库可以建立多个聚簇,一个关系只能加入一个聚簇。选择聚簇存取方法,即确定需要建立多少个聚簇,每个聚簇中包括哪些关系
起首计划候选聚簇,一样平常来说:

  • 对常常在一起举行毗连操纵的关系可以建立聚簇。
  • 假如一个关系的一组属性常常出现在相等比较条件中,则该单个关系可建立聚簇
  • 假如一个关系的一个(或一组)属性上的值重复率很高,则此单个关系可建立聚即对应每个聚簇码值的平均元组数不能太少,太少则聚簇的效果不明显。
然后查抄候选聚簇中的关系,取消其中不须要的关系:

  • 从聚簇中删除常常举行全表扫描的关系。
  • 从聚簇中删除更新操纵远多于毗连操纵的关系。
  • 差别的聚簇中大概包罗相同的关系,一个关系可以在某一个聚簇中,但不能同时加入多个聚簇。要从这多个聚簇方案(包括不建立聚簇)中选择一个较优的,即在这个聚簇上运行各种事务的总代价最小。
留意事项

使用聚簇索引有以下几个留意点:

  • 一张表只能有一个聚簇索引,由于聚簇索引会影响数据的物理存储。
  • 聚簇索引的建立需要考虑聚簇键的选择,通常要选择唯一性较高的列作为聚簇键。
  • 更新聚簇索引列的开销较大,由于更新操纵大概会引起数据的物理移动,并使此关系上原来建立的所有索引无效,必须重建。因此在对聚簇索引列举行大量更新操纵的场景中,建议不要使用聚簇索引。
  • 当一个元组的聚簇码值改变时,该元组的存储位置也要做相应移动,聚簇码值要相对稳定,以减少修改聚簇码值所引起的维护开销。
  • 聚簇索引和非聚簇索引(即普通索引)的建立是互不影响的,可以在相同的表上同时使用这两种索引。
  • 其当 SQL 语句中包罗有与聚簇码有关的 ORDER BY、GROUP BY、UNION、DISTINCT 等子句或短语时,使用聚簇特殊有利,可以省去对结果集的排序操纵;否则很大概会适得其反。
缺点



  • 插入速度严重依赖于插入顺序,按照主键的顺序插入是最快的方式,否则将会出现页分裂,严重影响性能。
    因此,对于 InnoDB 表,我们一样平常都会定义一个自增的 ID 列为主键(主键列不要选没有意义的自增列,选常常查询的条件列才好,不然无法体现其主键索引性能)
  • 更新主键的代价很高,由于将会导致被更新的行移动。因此对于InnoDB 表,我们一样平常定义主键为不可更新。
非簇状索引(辅助索引)

非聚簇索引(Non-Clustered Index)是在表的某一列上建立的索引,与聚簇索引差别,非聚簇索引并不改变数据的物理存储顺序
非聚簇索引通过创建一个独立的数据布局,使得查询操纵更加高效。它包罗索引列的值以及指向相应数据行的指针或物理地址。
以下是关于非聚簇索引的一些要点:

  • 一张表可以有多个非聚簇索引,通过在差别的列上建立索引,可以更灵活地支持差别的查询操纵。
  • 非聚簇索引可以加快数据检索的速度,由于查询操纵起首通过索引找到相干的记录,然后再通过指针或物理地址找到具体的数据行。
  • 非聚簇索引对于频繁更新的表更加友爱,由于它的更新操纵不需要像聚簇索引一样移动数据行。
  • 在某些环境下,查询操纵需要访问多个非聚簇索引来获取完备的结果集,这大概会导致额外的 I/O 开销。
  • 二级(辅助)索引访问需要两次索引查找,第一次找到主键值,第二次根据主键值找到行数据。
索引的底层数据布局

索引是在存储引擎层实现的,而不是在服务器层实现的,所以差别存储引擎具有差别的索引范例和实现。
MySQL 中常用的索引布局(索引底层的数据布局)有:B树 ,B+树,HASH 等。
索引是对记录集的多个字段举行排序的方法。在一张表中为一个字段创建一个索引,将创建另外一个数据布局,包罗字段数值以及指向相干记录的指针,然后对这个索引布局举行排序,允许在该数据上举行二分法排序。将时间复杂度缩小到                                    O                         (                         l                         o                                   g                            2                                  N                         )                              O(log_2N)                  O(log2​N)
B-Tree

B-Tree(B树)是一种用于存储和构造数据的均衡搜索树数据布局,其计划目标是提供高效的插入、删除和查找操纵,同时能够适应频繁的数据更新和范围查询。
特点

B-Tree 的特点包括:

  • 均衡性:B-Tree 是一棵均衡树,它的所有叶子节点都位于相同的深度,这样可以确保树的高度相对较小,使得查找操纵的时间复杂度保持在较低的水平。
  • 多路性:B-Tree 的每个节点可以存储多个键值对,也就是多个子节点的指针。这样可以减少树的高度,提高查询效率。
  • 有序性:B-Tree 中的节点是按照键值的顺序存储的,使得范围查询操纵更加高效。
  • 磁盘友爱性:B-Tree 的计划考虑了磁盘块的读写特性,节点的大小通常和磁盘块的大小相当,树高一层意味着多一次的磁盘 I/O,从而可以最大限度地减少磁盘 IO 操纵。
特征



  • 关键字集合分布在整颗树中;
  • 任何一个关键字出现且只出现在一个结点中;
  • 搜索有大概在非叶子结点结束;
  • 其搜索性能等价于在关键字全集内做一次二分查找;
  • 自动条理控制;
B+ Tree

B+Tree 是大多数 MySQL 存储引擎的默认索引范例。InnoDB 和 MyISAM 存储引擎都默认使用 B+树 布局存储索引
由于不再需要举行全表扫描,只需要对树举行搜索即可,因此查找速度快很多。除了用于查找,还可以用于排序和分组。
可以指定多个列作为索引列,多个索引列共同组成键。
适用于全键值、键值范围和键前缀查找,其中键前缀查找只适用于最左前缀查找。假如不是按照索引列的顺序举行查找,则无法使用索引。
InnoDB 的 B+Tree 索引分为 聚簇索引(主索引)非簇状索引(辅助索引)
主索引的叶子节点 data 域记录着完备的数据记录,这种索引方式被称为聚簇索引。由于无法把数据行存放在两个差别的地方,所以一个表只能有一个聚簇索引。
辅助索引的叶子节点的 data 域记录着主键的值,因此在使用辅助索引举行查找时,需要先查找到主键值,然后再到主索引中举行查找。
只有 InnoDB 的主键索引才是聚簇索引,InnoDB 中的辅助索引以及 MyISAM 使用的都黑白聚簇索引。
特征



  • 所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰恰是有序的;
  • 不大概在非叶子结点中;
  • 非叶子结点相当于是叶子结点的索引(希罕索引),叶子结点相当于是存储(关键字)数据的数据层;
  • 每一个叶子节点都包罗指向下一个叶子节点的指针,从而方便叶子节点的范围遍历。
  • 更得当文件索引系统;
B+ 索引存取方法的选择


  • 假如一个(或一组)属性常常在查询条件中出现,则考虑在这个(或这组)属性上建立索引(或组合索引)。
  • 假如一个属性常常作为最大值和最小值等聚集函数的参数,则考虑在这个属性上建立索引。
  • 假如一个(或一组)属性常常在毗连操纵的毗连条件中出现,则考虑在这个(或这组)属性上建立索引。
关系上定义的索引数并不是越多越好,系统为维护索引要付出代价,查找索引也要付出代价。例如,若一个关系的更新频率很高,这个关系上定义的索引数不能太多。由于更新一个关系时,必须对这个关系上有关的索引做相应的修改。
Hash

哈希索引,采取肯定的哈希算法,把键值换算成新的哈希值,检索时不需要像 B+Tree 那样从根节点到叶子节点逐级查找,只需一次哈希算法即可立刻定位到相应的位置,能以                                    O                         (                         1                         )                              O(1)                  O(1) 时间举行查找,但是失去了有序性,它具有以下限定:


  • 无法用于排序与分组;
  • 只支持准确查找,仅仅能满意                                         =                                  =                     =,IN,                                        <                            =                            >                                  <=>                     <=> 查询,无法用于部分查找和范围查找,例如 WHERE age>18。
由于 Hash 索引比较的是举行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,由于经过相应的 Hash 算法处置处罚之后的 Hash 值的大小关系,并不能保证和 Hash 运算前完全一样。
InnoDB 存储引擎有一个特殊的功能叫“自适应哈希索引”,当某个索引值被使用的非常频繁时,会在 B+Tree 索引之上再创建一个哈希索引,这样就让 B+Tree 索引具有哈希索引的一些优点,好比快速的哈希查找。
Hash 索引存取方法的选择

假如一个关系的属性重要出现在等值毗连条件中,或重要出现在等值比较选择条件中,而且满意下列两个条件之一,则此关系可以选择 Hash 存取方法。

  • 一个关系的大小可预知,而且稳定。
  • 关系的大小动态改变,但数据库管理系统提供了动态 hash 存取方法
全文索引

MyISAM 存储引擎支持全文索引,用于查找文本中的关键词,而不是直接比较是否相等。查找条件使用 MATCH AGAINST,而不是普通的 WHERE。
全文索引一样平常使用倒排索引实现,它记录着关键词到其所在文档的映射。
InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引。
R-Tree

MyISAM 存储引擎支持空间数据索引 R-Tree,可以用于地理数据存储。空间数据索引会从所有维度来索引数据,可以有效地使用恣意维度来举行组合查询。
必须使用 GIS 相干的函数来维护数据。
索引存储在文件系统中

索引是占据物理空间的,在差别的存储引擎中,索引存在的文件也差别。存储引擎是基于表的,以下分别使用 MyISAM 和 InnoDB 存储引擎建立两张表。

存储引擎为 MyISAM
*.frm:与表相干的元数据信息都存放在 frm 文件,包括表布局的定义信息等
*.MYD:MyISAM DATA,用于存储 MyISAM 表的数据
*.MYI:MyISAM INDEX,用于存储 MyISAM 表的索引相干信息
存储引擎为 InnoDB
*.frm:与表相干的元数据信息都存放在 frm 文件,包括表布局的定义信息等
*.ibd:InnoDB DATA,表数据和索引的文件。该表的索引(B+树)的每个非叶子节点存储索引,叶子节点存储索引和索引对应的数据
总结

MySQL索引是优化数据库查询性能的重要手段。通过公道选择索引范例、制止索引冗余、限定索引数目以及公道使用联合索引,可以显著提高数据库的查询效率。然而,索引并非越多越好,过多的索引会增长写操纵的负担,因此在计划索引时需要综合考虑各种因素。
参考链接:
一文搞懂MySQL索引(清晰明了)-CSDN博客
MySQL - 索引(B+树) | Java 全栈知识体系 (pdai.tech)
SQL DB - 关系型数据库是如何工作的 | Java 全栈知识体系 (pdai.tech)
MySQL索引的创建与使用_ref字段索引-CSDN博客

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

莫张周刘王

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表