暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

关于数据库索引的一些常识

110

点击标题下「蓝色微信名」可快速关注

技术社群的这篇文章《超冷门!面试问我 SQL 回表?我瞬间懵了!》给我们讲解了索引覆盖、回表等相关知识,虽然说的MySQL,但对大部分关系型数据库原理都是通用的,可以学习借鉴。

一、索引覆盖

索引覆盖(Covering Index)或称为覆盖索引,是数据库中的一种优化手段。


当我们执行一个SQL查询时,如果只需要查询某几个字段的值,并且这几个字段的数据都已经被包含在某一个索引中(而不是全表扫描),那么数据库引擎就会直接通过这个索引来取得数据,而无需再回表查询,从而大大减少了I/O操作,提高了查询效率。


索引覆盖的优点就比如有:


  • 减少I/O次数: 因为通过覆盖索引可以直接获取数据,所以不需要再回表查询,从而减少了I/O次数。

  • 提高查询速度: 由于减少了I/O操作,查询速度自然也得到了提高。

  • 索引的选择性: 选择性是指不重复的索引值与数据表的总记录数的比值。选择性越高,通过索引筛选出的数据就越少,从而提高了查询效率。


这个我们就牵扯到回表查询了?面试官一般就会套路的继续往下问,那你知道回表操作么?


二、SQL回表


那么什么是 SQL 回表呢?


SQL回表,在MySQL数据库特别是InnoDB存储引擎中,是一个重要的概念。


SQL回表是指在使用非聚簇索引(也称为辅助索引或二级索引)进行查询时,由于非聚簇索引中只存储了索引字段的值和对应的主键(聚簇索引)键值,因此,如果需要获取非索引列的数据,则需要根据主键(聚簇索引)中的键值去查找实际的数据行。这个过程被称为“回表”。


回表的原理


  • 非聚簇索引结构: 非聚簇索引的叶子节点存储的是(索引列的值,主键的值)。

  • 查询过程: 当使用非聚簇索引进行查询时,首先通过非聚簇索引找到满足条件的主键键值。然后,根据这些主键键值,再回到聚簇索引(主键索引)中查找完整的数据行。


假设有一个用户表users,包含id(主键)、name和age三个字段,其中在name字段上建立了非聚簇索引。


执行查询SELECT * FROM users WHERE name='Tom'时,会发生回表。因为首先会通过name上的非聚簇索引找到满足条件的id,然后再根据这些id回到聚簇索引中查找完整的用户数据。


而查询SELECT id, name FROM users WHERE name='Tom'则不会回表,因为所需的数据都在非聚簇索引中可以找到。


而回表操作会增加I/O次数,从而可能影响查询性能。特别是在大表和复杂查询场景下,回表操作可能成为性能瓶颈。


为了减少回表操作,可以考虑将需要查询的字段加入到索引中,形成复合索引(也称为联合索引或覆盖索引)。这样,查询时就可以直接从索引中获取到需要的数据,而无需回表。


所以,建立索引的时候,我们要非常注意,并不是说索引不好,而是说要会加才可以。


三、索引的最左匹配原则


有的时候,我们建立索引大部分都不会只是单独的一个字段,所以就有了复合索引。


索引的最左匹配原则(Leftmost Prefix Rule) 主要是在使用复合索引(也称为多列索引或多字段索引)时的一个关键概念。这个原则指出,当使用复合索引进行查询时,查询条件应该尽可能地从索引的最左边开始匹配,这样索引才能被有效地使用。


当你基于复合索引进行查询时,查询条件必须包含索引的最左边的一列或多列,以便索引能够被有效地使用。例如,如果你有一个基于(last_name, first_name)的复合索引,以下查询可以有效地使用这个索引:


  • 查询基于last_name: SELECT * FROM employees WHERE last_name = 'Smith';

  • 查询基于last_name和first_name: SELECT * FROM employees WHERE last_name = 'Smith' AND first_name = 'John'; 但是,以下查询则不能有效地使用这个索引(因为它没有包含索引的最左边的列last_name):

  • 查询仅基于first_name: SELECT * FROM employees WHERE first_name = 'John';


在创建复合索引时,列的顺序很重要。你应该将最常用于查询条件的列放在索引的最左边。例如,如果你经常基于last_name进行查询,但很少基于first_name进行查询,那么你应该创建一个基于(last_name, first_name)的索引,而不是基于(first_name, last_name)的索引。


虽然最左匹配原则是一个重要的概念,但并不意味着你必须始终遵循它。在实际应用中,你需要根据查询的需求和数据的分布来决定是否使用复合索引以及索引的列顺序。


如果您认为这篇文章有些帮助,还请不吝点下文章末尾的"点赞"和"在看",或者直接转发朋友圈,

可以到各大平台找我,
  • 微信公众号:@bisal的个人杂货铺
  • 腾讯云开发者社区:@bisal的个人杂货铺
  • 头条号:@bisal的个人杂货铺
  • CSDN:@bisal
  • ITPub:@bisal
  • 墨天轮:@bisal
  • 51CTO:@bisal
  • 小红书:@bisal
  • 抖音:@bisal
近期更新的文章:
平均故障间隔时间(MTBF)的含义是什么?
看个中国足球的管理规定
世俱杯参赛名额的分配规则
圆桌共话|GB 级到 PB 级 MySQL 数据库国产化选型
金融知识小科普 - 稳定币
热文鉴赏:
揭开"仿宋"和"仿宋_GB2312"的神秘面纱
Linux的"aarch"是多了个"a"?
中国队“自己的”世界杯
你不知道的C罗-Siu庆祝动作
大阪环球影城避坑指南和功略
推荐一篇Oracle RAC Cache Fusion的经典论文
"红警"游戏开源代码带给我们的震撼
文章分类和索引:
公众号1700篇文章分类和索引

文章转载自bisal的个人杂货铺,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论