Mysql索引(一)

mysql索引优化实战一、二 MySQL索引优化实践总结:1.查询优化器会基于成本评估是否使用索引,范围查询可能导致全表扫描;2.强制索引可能因回表操作反而降低效率,覆盖索引可优化查询性能;3.索引使用与数据量相关,小表in/or查询可能不走索引;4.索引下推(5.6+)可减少回表次数,但范围查询不适用;5.排序优化遵循最左前缀原则,group by原理类似order by;6.join查询优先使用索引字段,小表驱动大表;7.count(*)≈count(1)效率最高;8.索引建立原则:联合索引覆盖高频查询,避免小基数字段索引,长字符用 阅读详情

概述

索引是存储引擎用于快速找到记录的一种数据结构。

举个例子:如果查找一本书中的某个特定主题,一般会先看书的目录(类似索引),找到对应页面。在MySQL,存储引擎采用类似的方法使用索引,高效获取查找的数据。

索引的分类

  • 从存储结构上来划分
    • Btree索引(B+tree,B-tree)
    • hash哈希索引
    • full-index全文索引
  • 从应用层次上来划分
    • 普通索引:一个索引只包含单个列,一个表可以有多个普通索引
    • 唯一索引:索引列的值必须唯一,但允许有空值
    • 复合索引:一个索引包含多个列
  • 从表记录的排列顺序和索引的排列顺序是否一致来划分
    • 聚簇索引(主键):表记录的排列顺序和索引的排列顺序一致。
    • 非聚簇索引:表记录的排列顺序和索引的排列顺序不一致。
  • 索引的原理

  • 索引一般以文件形式存在磁盘中(也可以存于内存中),存储的索引的原理大致概括为以空间换时间,数据库在未添加索引的时候进行查询默认的是进行全表扫描,有多少条数据
  • 就进行多少次查询,然后找到相匹配的数据就把他放到结果集中,直到全表扫描完。而建立索引之后,会将建立索引的key值放在一个n叉树(BTree)中。因为BTree的特点就是
  • 在磁盘等直接存储设备上进行动态查找,每次以索引进行条件查询时都会根据key值去树上直接搜索。
  • MySQL索引设计的核心目标是有效平衡数据检索的速度与存储效率。它使数据库能迅速定位数据,但数据库的挑战更为复杂因为需要处理各种查询类型,如等值查询、范围查询和
  • 模糊查询等。因此MySQL通过InnoDB 存储引擎采取了以下具体措施提高查询性能,也保证了数据的安全性和一致性:
    1. B+ 树索引结构:
      • 高效范围查询:B+树数据结构的平衡树特性保证了即使在大量数据中也能保持较低的查询深度,特别是对于范围查询,可以快速通过叶节点链表遍历相关数据
      • 优化读写性能:B+树的结构减少了节点分裂的频率,保持了树的平衡,从而提高了读写操作的效率
    2. 聚簇索引设计:
      • 直接存储数据:使用聚簇索引,其中表数据直接存储在索引的叶节点上。这意味着数据物理顺序与键值顺序一致,优化了顺序访问的性能
      • 减少I/O操作:通过聚簇索引,查询主键时直接定位到数据,无需额外的数据指针跳转,从而减少了磁盘I/O操作
    3. 数据页及预读机制:
      • 数据页单位操作:InnoDB以数据页为基本的I/O单位(默认 16 KB),这比单条记录的读写更高效,因为一次I/O可以加载多条记录到内存
      • 预读优化:利用操作系统的预读特性,InnoDB预测并提前加载可能访问的数据页到内存,减少了未来的I/O需求,尤其在顺序访问模式下效果显著
    4. 自适应哈希索引:
      • 内存级索引加速:当某些数据页被频繁访问时,InnoDB会在内存中自动构建哈希索引来加速这些数据页的访问,进一步减少了数据查找时间
    5. 写入缓冲与日志:
      • 写入合并:通过写入前日志(Write-Ahead Logging, WAL)和更改缓冲区(Change Buffer)技术,合并多个写入操作,减少对磁盘的直接写入,优化了写的性能。

索引的适用与不适用场景

索引的适用场景:

  • 经常用于查询的字段
  • 经常用于连接的字段建立索引,可以加快连接的速度
  • 经常需要排序的字段建立索引,因为索引已经排好序,可以加快排序查询速度

索引的不适用场景:

  • where 条件中用不到的字段不适合建立索引
  • 表记录较少
  • 需要经常增删改
  • 参与列计算的列不适合建索引
  • 要参与计算的列级区分度不高的列(如性别)

索引的设计原则

索引设计不合理或者缺少索引都会对数据库和应用程序的性能产生影响,高效的索引对获得良好的性能非常重要,设计索引时要考虑以下方面:

  1. 索引并非越多越好,大量的索引不仅占用磁盘空间,而且还会影响insert,delete,update等语句的性能,因为当表中的数据更改时索引也会相应的调整和更新
  2. 避免对经常更新的表做更多的索引,并且索引中的列尽可能少;对经常用于查询的字段创建索引,避免添加不必要的索引
  3. 数据量少的表尽量不要使用索引,由于数据较少,查询花费的时间可能比遍历索引的时间还要短,索引可能不会产生优化效果
  4. 在条件表达式中区分度高的列上创建索引,区分度低的列上不要建立索引。如果建立了索引不但不会提升效率,反而严重降低数据的更新速度
  5. 在频繁进行排序或者分组的列上建立索引,如果排序的列有多个,可以在这些列上建立联合索引
  6. 最左前缀原则:对于复合索引,确保查询条件能够利用索引的“最左前缀”。这意味着,查询条件应该从复合索引的第一个字段开始匹配,并且按照索引字段的顺序进行
  7. 选择性原则:优先为具有高选择性的列创建索引。选择性是指列中唯一值的比例,唯一值越多的列(接近列的总行数),选择性越高,索引效果越好
  8. 避免冗余和重复索引:检查并避免创建冗余或重复(一个索引是另一个索引前缀的)索引,因为这会增加额外的维护成本和空间消耗,而不会带来任何查询性能的提升
  9. 索引覆盖:如果一个查询可以通过访问索引就能获取所需的全部数据,那么这个索引被称为“覆盖索引”。设计时尽可能让索引覆盖更多查询,可以显著减少对磁盘的访问次数,提高查询效率
  10. 使用前缀索引以节约空间:对于长文本字段,可以考虑使用字段的前缀作为索引。前缀索引可以节省索引空间,降低维护成本,但需要权衡前缀长度和查询效率
  11. 索引维护:定期维护索引,包括重建或优化索引,以确保索引结构的效率。随着数据的增加和变化,索引可能会变得碎片化

索引的失效

在有些时候因为使用上的一些瑕疵就会导致索引的失效,无法达到我们使用索引的预期效果,下面介绍几种索引失效的场景:

  1. 列的对比:例如:某个表中,有两列 id 和 c_id 都建了单独索引,where 条件后为 id = c_id,这种情况会被认为还不如走全表扫描
  2. 存在Null值条件:如果索引列是可空的,是不会给其建索引的
  3. 存在Not条件:当查询条件为非时,索引定位就困难了,执行计划此时可能更倾向于全表扫描
  4. Like通配符:前匹配的情况下,执行计划会更倾向于选择全表扫描。后匹配可以走INDEX RANGE SCAN。所以业务设计的时候,尽量考虑模糊搜索更多的使用后置通配符
  5. 条件上包括函数:查询条件上尽量不要对索引列使用函数,因为索引在建立时会和计算后可能不同,无法定位到索引
  6. 复合索引前导列区分大:当复合索引前导列区分小的时候我们有INDEX SKIP SCAN,当前导列区分度大且查后导列的时候,前导列的分裂会非常耗资源,执行计划想还不如全表扫描来的快,然后就索引失效了
  7. 数据类型的转换:当查询条件存在隐式转换时,索引会失效。
  8. 使用非最左前缀查询:若索引是多列的(比如(a, b, c)),查询条件不是以索引的最左列开始,则索引可能不会被使用

InnoDB索引实现

InnoDB数据页有7个组成部分,各个数据页可以组成一个双向链表。而每个数据页中的记录会按照主键值从小到大的顺序组成一个单向链表,每个数据页都会为存储的记录生成一个页目录。在通过主键查找某条记录的时候可以在页目录中使用二分法快速定位到对应的槽,然后再遍历该槽对应分组中的记录即可快速找到指定的记录。

页和记录的关系示意图如下:索引同样存储在数据页中,只不过目录项中的两个列是主键和页号。在这里插入图片描述

那InnoDB怎么区分一条记录是普通的用户记录还是目录项记录呢?是根据记录头信息里的record_type属性,它的各个取值代表的意思如下:
0:普通的用户记录;1:目录项记录;2:最小记录;3:最大记录

如果我们想根据主键值查找一条用户记录大致需要3个步骤:

  1. 确定目录项记录页。
  2. 通过目录项记录页确定用户记录真实所在的页。
  3. 在真实存储用户记录的页中定位到具体的记录。

聚簇索引

什么是聚簇索引

InnoDB存储引擎表是索引组织表,表中数据按照主键顺序存放。其聚簇索引就是按照每张表的主键顺序构造一颗B+Tree,其叶子节点中存放的就是整张表的行记录数据,这些叶子节点称为数据页。

聚簇索引的存储并不是物理上连续的,而是逻辑上连续的,叶子节点间按照主键顺序排序,通过双向链表连接。多数情况下,查询优化器倾向于采用聚簇索引,因为聚簇索引能在

叶子节点直接找到数据,并且因为定义了数据的逻辑顺序,能特别快的访问针对范围值的查询。

聚簇索引的这个特性决定了索引组织表中的数据也是索引的一部分。由于表里的数据只能按照一颗B+Tree排序,因此一张表只能有一个聚簇索引。

在InnoDB中聚簇索引默认就是主键索引。如果没有主键,则按照下列规则来建聚簇索引:

  • 没有主键时,会用一个非空且唯一的索引列做为主键,成为此表的聚簇索引
  • 如果没有这样的索引,InnoDB会隐式定义一个主键来作为聚簇索引

由于主键使用了聚簇索引,如果主键是自增id,那么对应的数据也会相邻地存放在磁盘上,写入性能较高。如果是uuid等字符串形式,频繁的插入会使InnoDB频繁地移动磁盘块,

写入性能就比较低了。

InnoDB的B+Tree中的每个节点都是一个数据页,结构示意图如下:在这里插入图片描述
以上图为例子,实现快速查找主键为7的记录:

  1. 从根节点开始,通过二分法快速定位到符合页内范围包含查询值的页,因为查询的主键值为7,在 [1, 8) 范围之间,所以到页5中查找更详细的目录项
  2. 在非叶子节点页5中,继续通过二分法快速定位到符合页内范围包含查询值的页,主键值大于6,所以就到叶子节点页3查找记录;
  3. 接着在叶子节点页3中,通过槽查找记录时,使用二分法快速定位要查询的记录在哪个槽(哪个记录分组),定位到槽后,再遍历槽内的所有记录,找到主键为7的记录

可以看到,在定位记录所在哪一个页时,也是通过二分法快速定位到包含该记录的页。定位到该页后,又会在该页内进行二分法快速定位记录所在的分组(槽号),最后在分组内进行遍历查找。

聚簇索引列的选择

因为表的数据都是存放在聚簇索引的叶子节点里,所以InnoDB存储引擎一定会为表创建一个聚簇索引,且由于数据在物理上只会保存一份,所以聚簇索引只能有一个。

InnoDB在创建聚簇索引时,会根据不同的场景选择不同的列作为索引:

  • 如果有主键,默认会使用主键作为聚簇索引的索引键
  • 如果没有主键,就选择第一个不包含 NULL 值的唯一列作为聚簇索引的索引键
  • 在上面两个都没有的情况下,InnoDB 将自动生成一个隐式自增id列作为聚簇索引的索引键

非聚簇索引和二级索引

一张表只能有一个聚簇索引,那为了实现非主键字段的快速搜索,就引出了二级索引(非聚簇索引/辅助索引),它也是利用了B+Tree的数据结构,但是二级索引的叶子节点存放的是主键值,不是实际数据。二级索引的B+Tree如下图,数据部分为主键值:在这里插入图片描述

如果某个查询语句使用了二级索引,但是查询的数据不是主键值,这时在二级索引找到主键值后需要去聚簇索引中获得数据行,这个过程就叫作回表。也就是说要查两个B+Tree才能查到数据。不过,当查询的数据是主键值时,因为只在二级索引就能查询到,不用再去聚簇索引查,这个过程就叫作索引覆盖,也就是只需要查一个B+Tree就能找到数据。

其他索引的分类

索引的分类,可以根据角度的不同来分,在前面的内容,我们已经了解到了按 “数据结构(Hash 索引、B+ Tree 索引)” 以及按 “物理存储(聚合索引、二级索引)” 两种角度的索引分类,那么MySQL 中还存在着哪些形式的索引呢?

按字段特性分类

主键索引:主键索引就是建立在主键字段上的索引,通常在创建表的时候一起创建,一张表最多只有一个主键索引,索引列的值不允许有空值。

唯一索引:唯一索引建立在UNIQUE字段上的索引,一张表可以有多个唯一索引,索引列的值必须唯一,但是允许有空值。

普通索引:普通索引就是建立在普通字段上的索引,既不要求字段为主键,也不要求字段为 UNIQUE。

前缀索引:前缀索引是指对字符类型字段的前几个字符建立的索引,而不是在整个字段上建立的索引,前缀索引可以建立在字段类型为 char、 varchar、binary、varbinary 的列

上。使用前缀索引的目的是为了减少索引占用的存储空间,提升查询效率。

按字段个数分类

单列索引:建立在单列上的索引称为单列索引,比如主键索引

联合索引:建立在多列上的索引称为联合索引

💡 联合索引范围查询:联合索引有一些特殊情况,并不是查询过程使用了联合索引查询,就代表联合索引中所有字段都进行了索引查询,也就是可能存在部分字段用到了,部分字段没有用到的情况。这种特殊情况就发生在范围查询,联合索引的最左匹配原则会一直向右匹配直到遇到范围查询就会停止匹配,也就是范围查询的字段可以用到联合索引,但是在范围查询字段的后面的字段无法用到联合索引。

最左前缀匹配原则:在MySQL建立联合索引时会遵守最左前缀匹配原则,即最左优先,在检索数据时从联合索引的最左边开始匹配。比如我们配置了一个 A、B、C 三个字段的联合索引,我们用 A、AB、ABC 的方式都是可以走到联合索引的,但如果是 AC、BC、C 的这种情况则不会使用索引。

索引下推

在MySQL5.6之前,当查询使用到联合索引时,MySQL会先根据索引的最左前缀原则,在索引上查找到满足条件的记录的主键或行指针,然后再根据这些主键或行指针到数据表中

查询完整的行记录。之后,MySQL再根据WHERE子句中的其他条件对这些行进行过滤。这种方式可能导致大量的数据行被检索出来,但实际上只有很少的行满足WHERE子句中

的所有条件。为了解决这个问题,MySQL 5.6引入了索引下推优化。

(Index Condition Pushdown, ICP)是MySQL优化查询的一种方式,其核心思想是将原本在服务层(上层)进行的部分过滤操作下推到存储引擎层(下层)执行,从而减少不必要

的数据行检索,提高查询效率。这样在扫描索引时,就可以提前过滤掉不满足条件的索引项,从而减少后续需要访问的数据行数。

具体说就是当MySQL使用ICP时,它会将WHERE子句分为两部分:一部分是只涉及索引列的条件(称为索引条件),另一部分是涉及非索引列的条件(称为表条件)。MySQL会

先将索引条件下推到索引扫描的过程中,然后再根据表条件对结果进行过滤。

没有使用ICP的查询过程

  1. 解析查询:MySQL服务器接收到SQL查询后,首先会解析查询,确定需要访问哪些表和索引。
  2. 索引查找:服务器根据解析结果,利用存储引擎提供的接口,在索引中查找满足条件的索引项。这个过程中,存储引擎只会根据索引的键值进行查找,不会考虑WHERE子句中的其他条件。
  3. 数据行检索:服务器获取到满足索引条件的索引项后,会进一步根据这些索引项中的指针(或主键值)到数据表中检索出完整的行数据。
  4. 过滤行数据:服务器在检索出数据行后,会在服务层根据WHERE子句中的其他条件对这些行进行过滤,只保留满足所有条件的行。
  5. 返回结果:最后,服务器将过滤后的结果返回给客户端。

使用ICP的查询过程

  1. 解析查询:MySQL服务器会首先解析查询,确定需要访问的表和索引。
  2. 索引查找与部分过滤:与没有使用ICP不同的是,在使用ICP时,服务器会将WHERE子句中的部分条件(索引条件)下推到存储引擎层。存储引擎在查找索引项的过程中,会同时根据这些下推的条件进行过滤,只返回满足索引条件和部分WHERE条件的索引项。
  3. 数据行检索与最终过滤:服务器根据过滤后的索引项检索出数据行,此时的数据行已经大大减少了。然后,服务器会在服务层根据WHERE子句中的剩余条件对这些行进行最终的过滤。
  4. 返回结果:服务器将最终过滤后的结果返回给客户端。

💡 通过ICP优化,可以在存储引擎层就过滤掉大量不满足条件的数据行,从而减少了数据行检索的数量和服务层过滤的工作量,提高了查询性能。尤其是在涉及到大量数据行和复杂WHERE条件的情况下,ICP优化的效果更为显著。

如何在执行计划中查看ICP的使用

通过EXPLAIN命令来查看查询的执行计划,判断是否使用了ICP优化。当执行计划中的Extra列显示Using index condition时,表示查询使用了ICP优化

使用限制

  • 复合索引查询:当查询使用到复合索引并且WHERE子句中有非索引列的条件时,ICP能够将索引列的条件下推到索引扫描的过程中,提前过滤不满足条件的索引项。
  • 访问方法限制:

range:当使用范围查询时,ICP可以有效地在索引扫描过程中过滤不满足条件的记录。

ref、eq_ref、ref_or_null:这些访问方法通常涉及到通过索引查找单个或多个匹配的行。在这些情况下,ICP可以帮助减少不必要的行查找。

  • 存储引擎限制:

InnoDB:InnoDB从5.6开始支持ICP,默认就是开启ICP的,想关闭的话可以通过命令SET optimizer_switch = 'index_condition_pushdown=off'

MyISAM:虽然MyISAM不支持事务处理,但它在某些场景下可能因为其高速的读取性能而被使用,MyISAM同样支持ICP

  • 索引类型限制:ICP优化只适用于二级索引(辅助索引)。在InnoDB中,主键索引的叶子节点直接包含行数据,而二级索引的叶子节点包含的是对应主键的值。因此,当使用二级索引进行查询时,MySQL首先查找到主键值,然后再根据主键值去查找实际的行数据。在这个过程中,ICP可以在查找主键值之前就过滤掉不满足条件的索引项,从而提高查询效率。
  • 优化器决策:即使查询满足上述条件,MySQL的优化器也不一定会选择使用ICP。优化器会根据查询成本估算来决定是否使用ICP。如果优化器认为全表扫描或者其他访问方法更快,它可能不会选择ICP。

索引合并

Index Merge Optimization是MySQL查询优化器在处理复杂查询时使用的一种高级技术。当查询的WHERE子句中有多个独立的条件,且每个条件都可以使用不同的索引时,

MySQL会尝试将这些索引合并起来,以提高查询效率。这种优化策略允许数据库在一个查询中同时使用多个索引,从而避免全表扫描或减少需要扫描的数据量。

为什么会有索引合并

因为在某些情况下,单独使用任何一个索引都无法高效地获取到完整的结果集。而通过合并多个索引的扫描结果,我们可以更精确地定位到满足所有条件的记录,从而提高查询效

率。考虑一个场景,你有一个大型的订单库,其中包含商品信息。你可能需要根据商品的名称、价格、分类等多个条件来检索商品。如果只依赖单个字段的索引,那么查询效率可

能会很低,因为你需要扫描大量的不相关记录。通过索引合并,MySQL可以利用多个字段上的索引来加速查询。它首先分别扫描每个索引,获取满足相应条件的记录集,然后再将

这些记录集合并,得到最终的结果。

主要类型

索引合并是MySQL优化复杂查询的一种有效策略,它允许数据库在单个查询中高效地利用多个索引。索引合并主要有三种类型:交集合并(Intersection Merge)、并集合并

(Union Merge)和排序并集合并(Sort-Union Merge),分别适用于不同的查询场景。在实际应用中,最好通过EXPLAIN命令来查看查询的执行计划,并根据实际情况进行调整

和优化。

交集合并(Intersection Merge):当查询需要满足多个条件(使用 AND 连接),并且每个条件都可以使用不同的索引时,MySQL会分别扫描这些索引,然后取结果的交集。

并集合并(Union Merge):在某些情况下,查询可能只需要满足多个条件中的任意一个(使用 OR 连接)。MySQL会分别扫描这些索引,然后取结果的并集。

排序并集合并(Sort-Union Merge):这是一种特殊情况,主要发生在需要对结果进行排序,并且排序的字段也有索引时。MySQL会分别扫描索引,然后合并并排序结果。实际

上,MySQL的Index Merge策略并不直接支持排序并集合并。如果优化器决定使用索引合并,它可能会先执行交集或并集合并,然后再对结果进行排序。这里提到的“排序并集合并”

更多是为了理论上的完整性,实际执行计划可能会有所不同。

工作原理流程

  1. 条件分析:MySQL 优化器首先分析查询的WHERE子句,确定其中有多少个独立的条件。
  2. 索引选择:对于WHERE子句中的每个独立条件,优化器检查是否存在可用的索引。如果存在,它会评估使用这些索引的成本。
  3. 索引扫描:优化器决定使用哪些索引后,它会分别对这些索引进行扫描,获取满足每个条件的记录集。
  4. 结果合并:扫描完所有选定的索引后,MySQL将这些记录集合并,以产生最终的结果集。合并的方式可以是交集、并集或排序并集,具体取决于查询的条件和所需的结果。
  5. 返回结果:最终优化器将合并后的结果集返回给客户端。

应用场景

  • 多条件查询:当查询的WHERE子句中包含多个独立的条件时,每个条件都可以利用不同的索引。
  • 复合索引不完全匹配:即使你有一个复合索引(例如,INDEX(col1, col2)),但查询条件只涉及col1或col2时,MySQL可能会选择使用单列索引,并通过索引合并来优化查询。
  • 排序和限制:当查询需要排序或限制结果集大小时,索引合并可以帮助快速定位到满足条件的记录。

如何在执行计划中查看IMO的使用

使用EXPLAIN语句可以查看查询的执行计划,如果type列显示为 index_merge,则说明MySQL使用了Index Merge Optimization。

使用限制

  • 在早期版本的MySQL中(特别是 5.6.7 之前),使用Index Merge Optimization有一个重要的前提,没有范围查询条件可以使用。这个限制在后续版本中得到了放宽。
  • 优化器基于统计信息和成本估算来决定是否使用Index Merge Optimization。如果优化器认为其他访问方法更高效,它可能会选择不使用索引合并。
  • 索引合并主要适用于SELECT查询。对于INSERT、UPDATE和DELETE操作,索引合并通常不适用。
  • 不是所有类型的索引都可以参与索引合并。通常,B-tree索引是参与索引合并的主要类型。
  • 索引合并最适用于WHERE子句中有多个独立条件的查询。这些条件应该能够分别使用不同的索引。
  • 在某些情况下,如果存在范围查询(如BETWEEN、<、>等)或ORDER BY子句,MySQL可能不会使用索引合并,而是选择使用单个索引或进行全表扫描。特别是当范围查询与索引合并不兼容时,优化器可能会放弃使用索引合并。
  • 如果某个索引的选择性很差(即该索引列中有大量重复值),则优化器可能不会选择该索引进行合并,因为它认为这样做不够高效。
  • MySQL优化器会根据统计信息、系统配置(如index_merge相关配置)以及查询的具体内容来决定是否使用索引合并。在某些情况下,即使满足了上述条件,优化器也可能选择不使用索引合并,因为它认为有更高效的执行计划。

索引覆盖

如果一个索引包含(或覆盖)所有需要查询的字段的值,称为覆盖索引。

覆盖索引为什么快

InnoDB存储引擎底层实现包括B+Tree索引和hash索引,InnoDB存储引擎默认是使用B+Tree。因为它良好的性能和特性更适合于构建高并发系统。根据索引的存储方式来划

分,索引可以分为聚簇索引和非聚簇索引。聚簇索引的特点是叶子节点包含了完整的记录行,而非聚簇索引的叶子节点只有索引字段和主键ID。非聚簇索引中因为不含有完整的数

据信息,查找完整的数据记录需要回表,所以一次查询操作实际上要做两次索引查询(回表)。而如果所有的索引查询都要经过两次才能查到,那么肯定会引起效率下降。覆盖索

引就实现了从非聚簇索引中直接获取数据,所以效率会提升。

如何在执行计划中查看索引覆盖的使用

使用EXPLAIN语句可以查看查询的执行计划,如果Extra列显示为using index,则说明MySQL使用了索引覆盖。

优缺点

覆盖索引是一种非常强大的工具,能大大提高查询性能,只需要读取索引而不需要读取数据。

优点:

  • 索引项通常比记录要小,所以MySQL访问更少的数据。
  • 索引都按值得大小存储,相对于随机访问记录,需要更少的I/O。
  • 覆盖索引对InnoDB尤其有用,因为InnoDB使用聚集索引组织数据,如果二级索引包含查询所需的数据,就不再需要在聚集索引中查找了。

限制:

  • 覆盖索引也并不适用于任意的索引类型,索引必须存储列的值。
  • Hash和full-text索引不存储值,因此MySQL只能使用BTree。
  • 不同的存储引擎实现覆盖索引都是不同的,并不是所有的存储引擎都支持覆盖索引。
  • 如果要使用覆盖索引,一定要注意SELECT列表值取出需要的列,不可以SELECT * ,因为如果将所有字段一起做索引会导致索引文件过大,查询性能下降。
基于ROS2系统开发机器人 以上是基于ROS 2开发机器人的基本流程和一个简单的发布者-订阅者示例。通过这个流程,你可以逐步扩展和优化你的机器人系统,实现更复杂的功能。 阅读详情

相关推荐

ZedBoard+Vivado(二)——PS + PL实现流水灯

硬件:Zedboard 软件:Vivado2018.2 + Win10 本文参考了http://blog.chinaaet.com/cuter521/p/35978的设计 1 设计 功能:PS + PL流水灯 语言:C 流程:创建工程-&amp;gt;IP Integrator-&amp;gt;综合、实现、生成Bitstream-&amp;gt;SDK 2 流程 2.1 创建工程 跟上一篇步骤完全相同,这里不用添加源文...

q416524389的博客 3694

Mysql索引的结构以及查询一条记录的流程

InnoDB读取数据、B+树结构

m0_47160811的博客 983

磁带库Scalar i6000界面基本操作步骤

(注:磁带库的前面的门不要打开,日常维护:主要就是简单看下磁带库的状态;绿色代表正常;黄色代表报警但不影响磁带库正常使用;红色代表报警,不能正常使用,及时和厂家联系报修。) 一、磁带库管理页面 1、首先,磁带库前面(具体作用如图) 2、查看状态和管理页面 3、管理页面登陆。用户名:service 密码:xxxxxx 4、磁带机背面 二、电脑连接磁带库进入管理页面 1.用网线把电脑和磁带库的维护接口(磁带库背面)进行连接 2.电脑环境:JAVA。把电脑的IP设置成自...

杀神lwz的博客 5352

Mysql-如何正确的使用索引以及索引的原理

一、 介绍 二、 索引的原理 三、 索引的数据结构 四、 聚集索引与辅助索引 五、 MySQL索引管理 六、 测试索引 七、 正确使用索引 八、 联合索引与覆盖索引 九、 查询优化神器-explain 十、 慢查询优化的基本步骤 十一、 慢日志管理 一 、介绍 为何要有索引?   一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很...

285

【GAMES201学习笔记】物质点法入门

《GAMES201》 学习笔记

捕鱼维的个人小站 9199

React项目实战:用AntV G6打造可折叠组织架构图(附完整代码)

本文详细介绍了如何在React项目中使用AntV G6库构建一个功能完整的可折叠组织架构图。通过实战代码演示了从环境搭建、自定义节点、折叠状态管理到性能优化的全流程,重点解决了企业级应用中处理复杂树形数据、实现流畅交互等核心问题,并提供了可直接复用的组件代码。

weixin_29016315的博客 312

尼尧的面试日记:面试记录(三)

最近开始找工作了,坐标杭州。渣渣感觉面试应该挺困难的,也不知道具体会问哪些类型,会在面试完把每一次面试问到的题目列出来, 一个作用是参考记录,另一个作用是可以把自己不会或者弱项的问题及时补齐。 暂时是先把问题列出来,有时间的时候会把答案补上。 希望能找到一个好工作,加油 尼尧的面试日记:面试记录(三)本次面试过程面试题一、你先简单介绍一下自己吧。二、了解mysql吗,那先说一下数据库的主键索引和普通索引的区别。三、刚才听你说到聚集索引,那你说说(后提醒这是联合索引,你记错了)。四、线程池知道吗,说说其中的参

尼尧Nier的博客 358

Trae编程工具Cline插件深度集成与Claude 3.7 API Key高级配置实战

本文详细介绍了如何在Trae编程工具中深度集成Cline插件并配置Claude 3.7 API Key的高级技巧。通过实战案例,展示了如何提升代码补全质量、实现多轮对话记忆及自定义代理设置,特别适合全栈工程师和需要私有化AI服务的团队。文章还涵盖了安装流程、API Key获取方式及企业级部署的最佳实践。

weixin_28829903的博客 436

MySQL索引原理以及查询优化

MySQL索引原理以及查询优化 一、介绍 1.什么是索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句的优化显然是重中之重。说起加速查询,就不得不提到索引了。 2.为什么要有索引呢? 索引在MySQL中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构。...

Silverfeathers 246

Mac用户解决WPS中的俄语显示红线问题(WPS添加外语拼写检查)

我所使用的WPS版本:AppleStore 下载的 MacOs版 3.3.0 首先,对于 在访达-应用程序中,找到WPS,右键-点击“显示包内容” 然后按照下图的索引目录(Contents\Resource\office6\dicts\spellcheck),最后进入一个叫“spellcheck”的文件夹 最后将下载好的字典包(例如上图中的 en_US就代表美式英语;ru_RU就代表俄语) 关于字典包资源下载,我在网上找到一个Google云盘,里面包含了法语,德语,西语,意大利语,葡萄牙.

qq_48159150的博客 7893

脉冲变压器电感选型参数,结构原理,工艺与注意问题总结

脉冲变压器电感简称脉冲变压器,是一种特殊类型的变压器,主要用于处理脉冲信号。它的主要特性是能够在短时间内承受高电压和大电流。脉冲变压器主要用于开关电源、脉冲功率放大、雷达脉冲调制等领域。本文对脉冲变压器的工作原理,结构特点,工艺流程,选型参数及设计注意事项进行总结。

fydar的博客 1342

一、Mysql 索引

一、什么是索引 索引是帮助MySQL高效获取数据的排好序的数据结构 索引常用的数据结构:二叉树、红黑树、Hash表、B-Tree,MySQL当前使用的是B+Tree,B+Tree是B-Tree的变种。 B-Tree特性: 叶节点具有相同的深度,叶节点的指针为空 所有索引元素不重复 节点中的数据索引从左到右递增排序 索引有可能在非叶子节点结束 自动分层控制 B+Tree特性: 非叶子节点不存储data,只存储索引,可以放更多的索引 叶子节点包含所有索引字段,所有查找都在叶子节点结束 叶子节点用指针连接、提

Forrest Gump的博客 286

AI翻译工具自动翻译日语视频生成srt中文字幕,支持离线轻松生成任意日语视频字幕!可选择支持显卡模式和cpu模式低显存也能用

【AI离线字幕神器:日语视频一键转中文字幕】推荐一款基于Faster-Whisper的本地化字幕工具,可离线生成日语视频的中文字幕(.srt格式),支持CPU/GPU加速处理。实测1小时视频最快4-5分钟完成翻译,无需联网保护隐私。操作简单只需拖拽文件,支持批量处理音频(mp3/wav)和视频(mp4/mkv)文件,还能自定义输出格式和参数调整。特别适合需要观看无字幕日语资料的用户,堪称技术宅必备神器。下载地址附后,包含详细使用教程和参数配置说明。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1万+

MySQL索引优化实战一

一篇MySQL调优文章实战

tqq的博客 1457

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Mysql索引优化实战一

Mysql索引优化实战一

Zhuxiaoyu_91的博客 1229

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

mysql索引一(普通索引)

转自:https://blog.youkuaiyun.com/v_victor/article/details/52232685mysql常用的索引类型:主键索引、唯一索引、普通索引、全文索引、组合索引。

u012138706的专栏 2万+

MySQL索引优化一

MySQL索引优化一 索引结构 Explain分析 索引最佳实践

小二说码的博客 2254

一、 Mysql索引

一、 Mysql索引

weixin_45817985的博客 333

MySQL 索引(一)

你怎么保证,用户一定下次找的数据,就在这个Page里面?---->我们不能严格保证,但是有很大概率再一个Page当中或者是周围的,因为有局部性原理。数据库文件,本质其实就是保存在磁盘的盘片当中,就是一个一个的文件,找到一个文件的全部,本质,就是在磁盘找到所有保存文件的扇区。为了减少IO的次数,提高IO的效率,在单个page中,不在单个page中,会进行多次IO操作。花了6.17秒,就你一个人就花了6秒,如果公司人很多,会死机的。先整一个海量表,在查询的时候,看看没有索引时有什么问题?普通索引(index)

的博客 1832

MySQL 索引优化一

仅支持二级索引(辅助索引),聚簇索引无需下推(叶子节点已包含全量数据);过滤条件基于索引列,不支持函数 / 表达式(如age+1=23无法下推)。执行流程对比:1. 无索引下推执行流程:基数阈值:通常认为基数 / 表行数 < 5% 为小基数(需结合业务);例外:若小基数字段与高基数字段组成联合索引(如),仍可有效。

2403_85207115的博客 674

【MySQL深入】一、索引

本文深入解析MySQL InnoDB引擎的索引机制。核心要点包括:1)索引采用B+树结构,聚簇索引存储完整数据,非聚簇索引存储键值和主键;2)联合索引遵循最左前缀原则,相比单索引能减少查询次数;3)页分裂影响性能,有序主键可减少分裂;4)索引下推(ICP)和覆盖索引能显著提升查询效率;5)通过EXPLAIN分析type、key_len等指标可评估索引使用效率。文章还详细介绍了B+树存储计算、索引优化策略及常见性能问题诊断方法。

qq_43479628的博客 340

mysql 创建索引和删除索引一图小结

白菜编程之旅 241

MySQL索引(一)

备注:上述的二叉树索引结构只是一个示意图,并不是真实的索引结构。优缺点:Mysql索引是在存储引擎层实现的,不同的存储引擎有不同的结构,主要包含以下几种:我们平常所说的索引,如果没有特别指明,一般都是指B+树结构组织的索引。二叉树缺点:顺序插入时,会形成一个链表,查询性能大大降低。大数据量情况下,层级较深,检索速度慢。红黑树:大数据量情况下,层级较深,检索速度慢。 相对于B-Tree区别:​ 1、所有数据都会出现在叶子节点​ 2、叶子节点形成一个单向链表Hash索引: Hash索引特点:1、Hash索引只能

weixin_46073538的博客 242

MySQL索引优化系列:(一)索引的类型

MySQL 是最流行的关系型数据库管理系统,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS

菜菜bu菜的博客 1638

MySQL高级之索引一

MySQL高级之索引的数据结构一、索引的基础知识1. 基本概念2. 索引的优缺点2.1 优点2.2 缺点二、索引的数据结构1. Compact行格式简介2. 聚簇索引数据结构详解-B+树2.1 聚簇索引结构的演变2.1.1 数据数目不过页2.1.2 目录数目不过页2.1.3 目录数目过页2.1.4 总结2.1.5 更正3. 非聚簇索引数据结构3.1 从点到线:从聚簇到非聚簇3.1.1 区别一:叶子节点不存放数据3.1.2 区别二:不通过主键排序数据3.1.3 注意点:主键不可或缺3.2 举例 一、索引的

weixin_44446626的博客 793

【MySQL】索引(一)

一、磁盘1、物理结构2、示意图3、定位扇区4、读写操作的基本方式二、页1、介绍2、示例3、作用与结构4、类型(1)数据页(2)其他5、组织与管理6、性能优化7、示意图(B+树)三、索引1、作用2、注意事项四、非聚簇索引(Non-Clustered Index)1、介绍2、特点3、MyISAM(1)示例(2)说明4、示意图五、聚簇索引(Clustered Index)1、介绍2、特点3、innodb(1)示例(2)功能与作用4、示意图

Snow_Dragon_L的博客 852
上一篇: SQL执行原理
下一篇: Mysql索引(二)
geek-wmy
博客等级 码龄9年 322粉丝 126原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值