你管这叫数据库索引?

大家好,我是徒手敲代码。

今天来说一下面试中最常问到的,数据库索引。本文将尽量采用通俗易懂的语言,力求让读者可以轻松掌握,应付面试。

下面说的数据库,都是以MySQL为例。

1、什么是索引?

索引,可以类比成书的目录,通过直接翻书的形式,来找某个章节的话,可能会很慢,但是如果看了目录再翻,就会快很多。

索引在数据库中的应用也是类似这样。索引是建立在某个字段之上的,建了索引之后,在查询的时候,将这个字段作为查询条件,就可以快速定位到目标信息的位置,大大减少查询时间。比如:

sql 复制代码
select name from user where age = '20';

在这条 sql 中,查询年龄为 20 的用户,如果在 age 字段上建立了索引,那么将会大大提升查询效率。注意,是在查询条件的字段建索引,也就是 where 后面,才能发挥作用。

那是不是就意味着,我们可以无脑的创建索引呢?

当然不是。数据库无端端多了这么个东西出来,肯定会占用空间吧,并且在插入、修改、删除数据的时候,也会带来额外的开销。想想一下,在写一本书的时候,假设书是没有目录的,那么此时修改其中的内容,是非常的爽。但是一旦给书加上了目录之后,要修改书的内容,天啊,目录也要改,工作量不就一下子上来了嘛。

所以说上帝是公平的,要追求查询速度快,就必须要在存储空间和增删改的开销上,作出一定牺牲。不能既要、又要、还要喔。

2、有哪些常见的索引类型?

这个问题,可以从不同的角度来回答。

功能上看,索引可以分为:普通索引、唯一索引、主键索引、全文索引。理解他们的功能,直接从名字看就好了。

  • 普通索引:最普通的一种索引,没有任何的限制,字段可以有重复的值
  • 唯一索引:这个字段的值保证是唯一的
  • 主键索引:一般来说,每个表都会有一个名为 "id" 的字段,来作为主键索引,这个字段用来标识表里面,每一行记录的唯一性,而且每个表只能有一个主键索引,它的值不能为空,且保证唯一
  • 全文索引:一般用在对文本型的字段进行全文搜索,可以在一大段文字里面搜关键字

物理实现 上看,可以分为聚簇索引、非聚簇索引。区别就是叶子节点放的东西不一样

  • 聚簇索引:叶子节点放了一整行的内容。
  • 非聚簇索引:叶子节点只放了主键。

对于 MySQL 中最常用的存储引擎InnoDB,只有主键索引是属于聚簇索引,其他的索引都属于非聚簇索引,因此主键的值,不应该搞得过大,以免普通索引过于庞大。

3、为什么MySQL要用B+树作为InnoDB中索引的数据结构?

针对这个问题,务必记住以下这两个点。

  • 减少磁盘操作。B+树中,一个结点的子结点可以大于两个,这可以减少树的层数,在磁盘的数据存储里面,层数减少意味着磁盘的寻址次数也会减少,使得查询效率得以提高
  • 范围查找的优势。B+树的数据都存在叶子结点,这个可以使得一个数据页存放更多的结点,减少查询时从磁盘读写到内存的次数;而且叶子节点之间,是用指针相连,形成一个双向链表,这非常适合于数据库中常用的范围查询,知道头或尾,直接就能一整条查出来

4、MyIsam 和 InnoDB 的索引有什么区别?

MyIsam 和 InnoDB是MySQL中常见的两种存储引擎,它们底层的索引结构有所不同。

InnoDB 的主键索引,用的是聚簇索引。其他索引都是用非聚簇索引。

MyIsam 的全部索引,都是用非聚簇索引。

需要注意,使用 InnoDB 的表如果没有定义主键,那么会首先选一个唯一的非空列作为聚簇索引,如果连唯一的非空列都没有,那么会选择一个隐藏字段row_id作为表的主键,并且用作这个表的聚簇索引。

5、索引失效的场景

所谓的索引失效,就是 MySQL 优化器觉得,走了索引还不如不走查得快,或者说它想走,但是现实条件不满足。

  • 存在隐式类型转换。就是查询条件的参数类型,和索引的类型不一致,这种情况,MySQL只能扫描全表,在每条记录比较之前,将查询条件中的数据类型,转换成表里面的数据类型,再进行比较;
  • 使用了 like %xxx。这种情况,MySQL 根本无法找到索引树的入口,只能被迫扫描全表;
  • 查询条件中,包含了运算或者函数操作。这种情况,MySQL认为这个条件是不确定的(一个函数和一个具体的值,你说怎么比较),也就没办法找到索引树的入口;
  • 在联合索引中,条件没有用最左边的索引。比如联合索引 (a , b , c),而条件只有 b,这种情况不符合最左匹配原则;
  • 索引字段的值,区分度太小了。意思就是这个字段的值,很多行都是相同的,那用了索引,跟不用有什么区别?还不如直接扫描整张表

今天的分享到这里结束了,如果你喜欢这种讲解知识的方式,可以在下方留言喔。你的支持,是我创作的最大动力!


关注公众号"徒手敲代码",让我们在技术的星辰大海、生活的诗与远方中共勉同行,一起书写属于我们的精彩篇章!

相关推荐
㳺三才人子3 小时前
初探 Flask
后端·python·flask·html
星栈独行3 小时前
我在 Rust 全栈项目里用 JWT 做无状态认证
开发语言·后端·rust·前端框架·开源·github·web
Java爱好狂.3 小时前
Java程序员体系化学习路线(2026最新版)
java·后端·java面试·java架构师·java程序员·java八股文·java学习路线
陈随易4 小时前
Redis 8.8发布,一定要更新
前端·后端·程序员
装不满的克莱因瓶4 小时前
SpringBoot 如何将 lib 目录中jar包打包进最终的jar包里面
spring boot·后端·maven·jar·mvn
ltl5 小时前
Transformer 原论文实验结果:为什么 28.4 BLEU 足以改写路线图
后端
excel5 小时前
为什么我推荐使用 Termius:现代 SSH 工具的完整体验
前端·后端
卷毛的技术笔记6 小时前
Java后端硬核实战:用Spring AI Alibaba+Redis给LLM装上“超强记忆中枢”
java·人工智能·redis·后端·spring·ai·系统架构
IT_陈寒7 小时前
Java的Optional差点让我掉坑里,这几个坑你别踩
前端·人工智能·后端
子兮曰7 小时前
Harness 驾驭工程深度教程:从 AGENTS.md 到全链路 AI 编码基础设施
前端·后端·ai编程