为什么SQL语句命中索引比不命中索引要快?

简介: 有位粉丝面试高开的时候被问到,为什么SQL语句命中索引比不命中索引要快?虽然自己也知道答案,但被问到的瞬间,就不知道如何组织语言了。今天,我给大家深度分析一下。

有位粉丝面试高开的时候被问到,为什么SQL语句命中索引比不命中索引要快?虽然自己也知道答案,但被问到的瞬间,就不知道如何组织语言了。今天,我给大家深度分析一下。

1、索引的作用

想象一下,现在有一本包含几十万字的字典,有几百页厚,同时里面的字是无序排列的。如果在不使用目录的情况下,我们如何从字典中找出需要的字来呢?毫无疑问,我们只能一页一页的翻,显然,这是一项反人类的的工作。

f8b6381ec576d2df55d18064a8e00398.jpg

我们必然想的是先看目录,然后,找到相关的字或者偏旁,然后,找到对应的页码再去查找想要找的文字,这样,效率就大大提高了。而事实上,目录就是一种索引,我们说的数据库索引思想和目录的思想一脉相承。

数据库索引最主要的作用就是帮助我们快速检索到想要的数据,从而不至于每次查询都做全局扫描。

假设不使用任何算法的情况下,我们要查询10万条记录中的某一条,在最坏的情况下需要遍历10万次。

289ad233005de80dc1b03df554ab8b50.jpg

但如果使用二分查找算法,则只需要进行log2 20000次,也就是14.287712次即可。这意味着我们只需对排序后的值进行14次搜索,就可以使用二分查找到想要的唯一值,常见的索引数据结构有B树和B+树。

下面我们,以MySQL的InnoDB引擎为例,分析一下索引的工作原理。

2、索引执行原理

我们知道MySQL的InnoDB引擎采用的是B+树数据结构,当我们去执行SELECT语句查询数据的时候,InnoDB需要从磁盘上去读取数据,而这个过程会涉及到磁盘 以及磁盘的随机IO ,我们来看这么一个图:

19e9d1e90ed01098a30041bb875de5f9.jpg

系统会把数据的逻辑地址传给磁盘,磁盘控制线路按照寻址逻辑把逻辑地址翻译成物理地址。也就是确定要读取的数据在哪个磁道、哪个扇区。为了读取这个扇区的数据,需要把磁头放在这个扇区上面,为了实现这样一个点,磁盘会不断地去旋转。把目标扇区旋转到磁头下面,使得磁头能够去找到对应的磁道。这里还会涉及到寻道的时间以及旋转时间的一个损耗。很明显磁盘IO这个过程的性能开销是非常大的,尤其是查询的数据量比较多的情况下。

所以InnotDB里面,干脆对存储在磁盘上的数据建立一个索引,然后把索引数据以及索引列对应的磁盘地址以B+树的方式进行存储。来看这么一个图:

8c78d4ccff2db7e01f6f9717d1dee1dd.jpg

当我们需要查找目标数据的时候,根据索引从B+树中去查找目标数据就行了。由于B+树的子树比较多,所以,只需要较少次数的磁盘IO就能够查找到目标数据。

至于B+树的数据结构,在这里就不分析了。大家可以去我的个人主页看往期视频有讲到。

3、索引的弊端

虽然,使用索引能减少磁盘IO次数,提高查询效率,但是,索引也不能建立太多。如果一个表中所有字段的索引很大,也会导致性能 l下降。想象一下,如果一个索引和一个表一样长,那么它将再次成为一个需要检查的开销。这就好比字典的目录非常详细,但是其长度已经和所有的文字一样长,这个时候目录本身的效率就大大下降了。

那索引有弊端吗?肯定是有的,索引可以提高查询读取性能,而它会将降低写入性能。当有索引时,如果更改一条记录,或者在数据库中插入一条新的记录,它将执行两个写入操作(一个操作是写入记录本身,另一个操作是将更新索引)。

9fb52176b6010e59d4000e7e9f45984c.jpg

因此,在定义索引时,必须牢记以下几点:

1、索引表中的每个字段将降低写入性能。

2、建议使用表中的唯一值为字段编制索引。

3、在关系数据库中充当外键的字段必须建立索引,因为它们有助于跨多个表进行复杂查询。

4、索引还使用磁盘空间,因此在选择要索引的字段时要小心。

最后,我把之前分享的视频全部整理成了文字,想获取的小伙伴可以扫描文章底部二维码拿!希望能够以此来提高各位粉丝的通过率。

image.gif

我是被编程耽误的文艺Tom,只弹干货不掺水!你们的支持就是我最大的动力!关注我,面试不再难!



相关文章
|
1月前
|
SQL 存储 关系型数据库
如何巧用索引优化SQL语句性能?
本文从索引角度探讨了如何优化MySQL中的SQL语句性能。首先介绍了如何通过查看执行时间和执行计划定位慢SQL,并详细解析了EXPLAIN命令的各个字段含义。接着讲解了索引优化的关键点,包括聚簇索引、索引覆盖、联合索引及最左前缀原则等。最后,通过具体示例展示了索引如何提升查询速度,并提供了三层B+树的存储容量计算方法。通过这些技巧,可以帮助开发者有效提升数据库查询效率。
107 2
|
1月前
|
SQL Oracle 关系型数据库
SQL优化-使用联合索引和函数索引
在一次例行巡检中,发现一条使用 `to_char` 函数将日期转换为字符串的 SQL 语句 CPU 利用率很高。为了优化该语句,首先分析了 where 条件中各列的选择性,并创建了不同类型的索引,包括普通索引、函数索引和虚拟列索引。通过对比不同索引的执行计划,最终确定了使用复合索引(包含函数表达式)能够显著降低查询成本,提高执行效率。
|
1月前
|
SQL 关系型数据库 MySQL
如何确认SQL用了索引:详细技巧与方法
在数据库管理中,索引是提高SQL查询性能的重要手段
|
2月前
|
存储 SQL 关系型数据库
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
MySQL调优主要分为三个步骤:监控报警、排查慢SQL、MySQL调优。 排查慢SQL:开启慢查询日志 、找出最慢的几条SQL、分析查询计划 。 MySQL调优: 基础优化:缓存优化、硬件优化、参数优化、定期清理垃圾、使用合适的存储引擎、读写分离、分库分表; 表设计优化:数据类型优化、冷热数据分表等。 索引优化:考虑索引失效的11个场景、遵循索引设计原则、连接查询优化、排序优化、深分页查询优化、覆盖索引、索引下推、用普通索引等。 SQL优化。
541 15
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
|
2月前
|
存储 关系型数据库 MySQL
MySQL高级篇——覆盖索引、前缀索引、索引下推、SQL优化、主键设计
覆盖索引、前缀索引、索引下推、SQL优化、EXISTS 和 IN 的区分、建议COUNT(*)或COUNT(1)、建议SELECT(字段)而不是SELECT(*)、LIMIT 1 对优化的影响、多使用COMMIT、主键设计、自增主键的缺点、淘宝订单号的主键设计、MySQL 8.0改造UUID为有序
MySQL高级篇——覆盖索引、前缀索引、索引下推、SQL优化、主键设计
|
1月前
|
SQL 存储 关系型数据库
SQL默认索引是什么:深入解析与技巧
在SQL数据库中,索引是一种用于提高查询性能的重要数据结构
|
2月前
|
SQL 存储 索引
SQL Server的Descending Indexes降序索引
【9月更文挑战第21天】在SQL Server中,降序索引允许指定列的排序顺序为降序,可显著优化涉及降序排序的查询性能,特别是在复合索引中。通过创建降序索引,可以更高效地满足特定业务需求,如按交易时间降序获取最新记录。然而,使用时需考虑查询频率、数据分布及维护成本,以确保最佳性能。
|
1月前
|
SQL 存储 关系型数据库
SQL默认索引是什么
在SQL数据库中,索引是一种用于提高查询性能的数据结构
|
1月前
|
SQL 关系型数据库 MySQL
如何确认SQL用了索引
在数据库管理和优化过程中,确认SQL查询是否使用了索引是一个至关重要的步骤
|
1月前
|
SQL 关系型数据库 MySQL
如何确认SQL查询是否使用了索引:详细步骤与技巧
在数据库管理和优化中,确认SQL查询是否有效利用了索引是提升性能的关键步骤