索引为什么这么快

一、从一个生活场景开始:没有索引有多慢?

1.1 假设你有一张用户表

你的程序里有一张 user 表,存了 5 个用户的数据,保存在电脑硬盘上:

 
硬盘上的样子(数据按插入的先后顺序随便堆放):
 
位置1: | id=3, name="王五", age=25, city="上海" |
 
位置2: | id=1, name="张三", age=20, city="北京" |
 
位置3: | id=5, name="赵七", age=30, city="深圳" |
 
位置4: | id=2, name="李四", age=22, city="广州" |
 
位置5: | id=4, name="钱六", age=28, city="杭州" |
 

1.2 如果我要找 id=4 的人

MySQL 只能这样做:

 
从位置1开始,读第一条 → id=3,不是4,跳过
 
读位置2 → id=1,不是4,跳过
 
读位置3 → id=5,不是4,跳过
 
读位置4 → id=2,不是4,跳过
 
读位置5 → id=4,找到了!
 

5 条数据里找一个,最坏要翻 5 次。如果表里有 100 万条数据呢?最坏要翻 100 万次。每一次翻动都是一次磁盘读取(硬盘读写),而硬盘的速度比内存慢几千倍。

核心问题:数据在硬盘上是乱序堆着的,找东西只能一行一行翻。数据越多越慢。

1.3 生活中我们怎么解决这个问题?

字典的目录。你要查”张”字,不会从第一页翻到最后一页,而是:

 
1. 翻到"拼音目录"(这个目录很薄,只有几页)
 
2. 找到"Z"开头的部分
 
3. 目录告诉你:"张"字在第 528 页
 
4. 直接翻到 528 页
 

这个拼音目录,就是索引。

1.4 数据库里索引是什么?

索引 = 给数据额外建一个”目录”,这个目录排好序了,查起来飞快。

目录长什么样?比如给 id 列建索引:

 
id 索引(排好序的小本本):
 
索引项: | id=1 → 数据在位置2 |
 
        | id=2 → 数据在位置4 |
 
        | id=3 → 数据在位置1 |
 
        | id=4 → 数据在位置5 |
 
        | id=5 → 数据在位置3 |
 
现在找 id=4:
 
  看索引中间:id=3,4>3 → 往后看
 
  看到 id=4 → 数据在位置5 → 直接去位置5拿数据
 
  只翻了几次索引(很小的目录)+ 1次拿数据,而不是翻遍全表
 

所以索引的本质就是:花一点额外的存储空间,建一个排序好的”目录”,让查找从”翻遍全部”变成”翻几下目录 + 直接定位”。

(这也是为什么里常说”索引是用空间换时间”——多占用一些硬盘空间存目录,换来找数据的速度。)

1.5 索引不是免费的

代价什么意思
占硬盘空间索引本身也要存,数据越多索引越大
拖慢增删改每次新增、删除、修改数据,索引这个”目录”也要同步更新
不能乱建建了不用的索引,白占空间还拖慢写入

二、一图流(Mermaid)


flowchart TD

    A[要找 id=4] --> B{有索引?}

    B -->|否 全表扫描| C["逐行翻硬盘 最坏 100万次 IO"]

    B -->|是 走索引| D["翻薄薄的排序目录 几次定位"]

    D --> E["直接去数据所在位置拿 → 1次 IO"]

    C --> F[慢: 数据越多越慢]

    E --> G[快: 与数据量无关]

▶ 对应实操:08-EXPLAIN执行计划分析

速记卡(面试闪卡)

Q1:一句话讲清「索引为什么这么快」到底是什么?

A:数据库索引是给数据额外建的排好序的”目录”,把查找从全表逐行翻硬盘变成翻几下目录再直接定位,本质用空间换时间。

Q2:没有索引多慢(full table scan) —— 怎么理解?

A:类比:没索引的数据像乱堆的仓库,找 id=4 得从位置1翻到尾,100万行最坏翻100万次磁盘(disk IO),硬盘比内存慢几千倍。数据越多越慢,纯靠蛮力。(Brute scan)

Q3:索引怎么加速(B+ tree) —— 怎么理解?

A:类比:索引像字典的拼音目录——薄薄几页、排好序。找”张”先翻目录定位第528页再直取,而不是从第一页翻到末页。B+树(B+ tree)索引树高约3层,100万行也只需约3次 IO 而非100万次。(Sorted index)

Q4:索引不是免费的(trade-offs) —— 怎么理解?

A:类比:索引像办了张会员目录卡:占硬盘空间(数据越多索引越大);拖慢增删改(每次写都得同步更新目录);不能乱建(用不上的索引白占空间还拖累写入)。空间换时间,账单别忘付。(Costs)

Q5:B+ 树为什么适合(why B+ tree) —— 怎么理解?

A:类比:B+树(B+ tree)像一棵矮胖查找树:节点排好序、叶子串成链表,三层就能管百万数据,每次比较砍掉一大半。相比二叉树它更”矮”,减少磁盘寻道次数——IO 次数是性能命门。(Short & wide)

Q6:核心速记主线有哪些?

  • 索引=排好序的目录,把全表扫描变成目录定位+直接取,空间换时间

  • 无索引最坏 IO 次数=数据行数;B+树索引约树高(~3)次

  • 代价:占空间、拖慢写(增删改同步更新)、不能滥用

  • B+树矮胖、叶子链表有序,减少磁盘寻道

  • 本质:用额外存储换查找速度

口诀

A:索引就是排序目录,空间换时间;

无索引翻全书,有索引查几页;

B+树矮又胖,三层管百万;

写入略买单,别建用不上的。

相关链接

相关链接