前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >覆盖索引与非覆盖索引的区别

覆盖索引与非覆盖索引的区别

原创
作者头像
一杯茶Ja
发布2024-11-30 16:15:11
发布2024-11-30 16:15:11
1390
举报

在开始之前,推荐大家阅读一篇文章《生成式AI在内容创作中的技术进展:以GPT模型为核心的分析与扩展原创》https://cloud.tencent.com/developer/article/2472442,该文章以 GPT 模型为核心,介绍了 AIGC 在文本生成中的应用、原理、实例及未来方向等内容,有兴趣的朋友可以去了解下。

前言

在数据库的索引体系中,覆盖索引和非覆盖索引是两个重要的概念,它们对于数据库查询性能有着不同程度的影响。了解二者之间的区别,有助于我们更合理地设计数据库索引结构,优化查询操作。以下将从多个方面详细阐述覆盖索引和非覆盖索引的区别。

一、定义

覆盖索引

覆盖索引是指一个索引包含了(或者说“覆盖了”)满足查询语句中所需要的所有数据列。也就是说,通过该索引就能直接获取到查询所要求的全部信息,无需再去访问数据表中的原始数据行。例如,我们有一张包含“姓名”“年龄”“地址”列的用户表,并且创建了一个包含“姓名”和“年龄”的复合索引,当执行查询语句“SELECT 姓名, 年龄 FROM 用户表 WHERE 年龄 > 18”时,这个复合索引就成为了覆盖索引,因为通过它就能获取到查询语句中所涉及的所有列的数据,无需再查找表中的其他数据了。

非覆盖索引

非覆盖索引则是指索引中并不包含查询语句所需要的全部数据列。当使用这类索引进行查询时,数据库系统在通过索引定位到相关记录的位置后,还需要进一步去数据表中读取其他未包含在索引里的数据列,才能完整地获取查询所需的全部信息。比如在上述的用户表中,只创建了基于“姓名”的单列索引,当执行查询“SELECT 姓名, 年龄 FROM 用户表 WHERE 姓名 LIKE '%张%'”时,仅靠这个“姓名”索引没办法得到“年龄”列的数据,就必须再去访问数据表本身来获取“年龄”列的内容,此时这个“姓名”索引就是非覆盖索引。

二、查询性能表现

覆盖索引

  • 优势:由于覆盖索引能直接提供查询所需的全部数据,减少了对数据表的访问次数,查询速度往往更快。特别是在数据量较大的情况下,避免了频繁地从磁盘读取数据表行数据,大大节省了 I/O 开销。例如在一个拥有百万条记录的电商订单表中,如果有一个覆盖索引包含了经常查询的“订单编号”“下单时间”“用户 ID”等列,那么当查询这些列相关信息时,数据库可以快速从索引结构中提取数据返回结果,效率会显著提高。
  • 劣势:覆盖索引虽然在特定查询场景下性能优越,但它需要占用额外的存储空间来存储索引数据。而且如果索引设计不合理,比如创建了过多不必要的覆盖索引或者索引包含了大量冗余的数据列,反而可能会影响数据库整体的性能,例如增加索引维护成本(在插入、更新、删除数据时都要同步更新相关索引)等情况。

非覆盖索引

  • 优势:在某些简单查询场景中,如果只是利用索引快速定位到符合条件的记录位置,后续对数据表的少量数据读取操作并不会带来过大的性能损耗。并且它相对覆盖索引来说,占用的存储空间可能会更小,因为不需要将所有可能查询的列都包含进索引中。例如,在一个员工信息表中,对于只偶尔查询员工“入职时间”的情况,仅创建基于“员工编号”的非覆盖索引,平时索引占用空间较小,在查询时若涉及其他列,按需去表中读取也能满足业务需求。
  • 劣势:当查询需要获取较多列的数据且这些列大多不在索引中时,就需要多次访问数据表,这会产生大量的磁盘 I/O 操作,从而导致查询性能下降。尤其是在处理复杂的关联查询或者多条件筛选查询且结果集较大时,频繁回表读取数据的开销会使得查询耗时明显增加。

三、使用场景

覆盖索引

  • 适用于频繁执行且查询列相对固定的查询操作,比如在报表统计类的应用场景中,经常需要查询固定的几列数据生成报表,像每天统计各门店的销售额、销售量等数据(假设相关数据列都可以通过合适的索引覆盖),创建覆盖索引就能让这类查询高效执行。
  • 在对响应时间要求极高的在线查询场景中,如果查询的数据列可以通过索引覆盖,那么使用覆盖索引可以快速返回结果,提升用户体验。例如电商平台上用户查询自己的订单列表,只展示订单编号、下单时间、商品名称等有限的几列信息,创建覆盖这些列的索引可以加速查询过程。

非覆盖索引

  • 多用于数据更新频繁,但查询相对简单且不需要获取太多列数据的场景。因为非覆盖索引占用空间相对较小,对数据更新操作的性能影响相对没那么大。例如,在一个社交平台的用户表中,用户的在线状态可能经常更新,而偶尔才会查询用户的注册时间等信息,此时基于用户 ID 等关键列创建非覆盖索引就比较合适,既能满足基本的查询定位需求,又不会因索引过大而严重影响更新性能。
  • 在一些临时性、不频繁的查询场景中,如果创建覆盖索引成本过高(如涉及大量列的复杂索引创建及维护),使用非覆盖索引结合少量的数据表回表读取操作也是可以接受的。

四、索引结构及维护成本

覆盖索引

  • 结构特点:覆盖索引往往包含了多个数据列(在复合索引的情况下),其结构相对复杂一些,内部的索引节点存储了满足覆盖条件的各列数据以及相应的索引键值。例如,一个包含了“产品名称”“产品分类”“价格”三列的覆盖索引,其索引结构中会按照一定的顺序(如基于“产品名称”排序,名称相同再按“产品分类”排序等)组织这些列的数据,方便快速查找。
  • 维护成本:因为覆盖索引包含的数据较多,所以在对数据表进行插入、更新、删除操作时,需要同时更新覆盖索引中对应的相关数据,维护成本相对较高。例如,当更新了某产品的价格,不仅数据表中的价格列要修改,包含价格列的覆盖索引中的对应数据也要同步更新,涉及到索引结构的调整等操作,会消耗一定的数据库资源。

非覆盖索引

  • 结构特点:通常只包含用于定位记录的关键列信息,结构相对简单。比如基于“学号”创建的单列索引,索引结构中主要就是按照学号的值进行排序存储,方便快速查找对应的学生记录位置。
  • 维护成本:由于非覆盖索引包含的数据列少,在数据变动时需要更新的索引内容也相对少一些,所以维护成本一般低于覆盖索引。不过在频繁更新索引键值所在列数据时(如频繁修改学号这种关键列),也会产生一定的维护开销,但整体相对覆盖索引在类似情况下的开销要小。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 一、定义
    • 覆盖索引
    • 非覆盖索引
  • 二、查询性能表现
    • 覆盖索引
    • 非覆盖索引
  • 三、使用场景
    • 覆盖索引
    • 非覆盖索引
  • 四、索引结构及维护成本
    • 覆盖索引
    • 非覆盖索引
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档