CodeGym /课程 /SQL SELF /索引原理:数据结构和查找算法

索引原理:数据结构和查找算法

SQL SELF
第 37 级 , 课程 4
可用

今天我们要更深入地聊聊索引的架构,看看它们底层到底是怎么运作的。其实,了解索引的结构不仅能让你明白为什么查询会变快,还能帮你为不同的任务选出最合适的索引。

说到索引结构,其实就是指索引内部数据是怎么组织的,这样才能保证查找速度快。想象一下有个文件柜。如果文件都乱堆在一起,找东西肯定很难。但如果柜子是按字母顺序排好的,查找就简单多了。索引就是这么回事:它们把数据排好队,让你能飞快地找到想要的信息。

B-TREE索引结构

B-TREE(balanced tree —— 平衡树)是PostgreSQL里最常用的索引类型。其实它就是一种树形结构,数据被分成节点,查找的时候会从树的根节点一路导航到叶子节点。

大致长这样:

         根节点
          /       |       \
      节点1    节点2    节点3
     /   \       |       /   \
叶子1 叶子2   叶子3  叶子4 叶子5

每个节点里都有关键值,用来引导查找。比如,假如根节点里有[10, 20, 30]

  • 所有小于10的数据都在叶子1。
  • 所有在1020之间的数据在叶子2,依此类推。

B-TREE索引的优点:

  • 查找速度快:查找复杂度是O(log n),比线性查找快多了。
  • 适合区间查找(比如找所有在1050之间的值)。

举个例子: 假设我们有个students表,里面有个age列。当我们在这个列上建B-TREE索引:

CREATE INDEX age_idx ON students (age);

PostgreSQL会为年龄值建一个平衡树,这样就能很快查到某个年龄或某个年龄段的学生。

B-TREE里的查找算法

当你执行查询时,PostgreSQL会这样用索引查找数据:

  1. 确定查找的key(比如年龄25)。
  2. 从根节点开始。
  3. 把key和节点里的区间比对,然后跳到对应的子节点。
  4. 重复第3步,直到到达叶子节点。
  5. 从叶子节点返回和key匹配的数据。

查询例子:

SELECT * FROM students WHERE age = 25;

索引能减少需要扫描的数据量,让查找变得很快。

查找算法和性能

索引能加速查找,是因为它们减少了需要扫描的行数。没有索引时,PostgreSQL会扫描整张表(这叫顺序扫描,也就是Seq Scan)。有了索引,就会用索引扫描Index Scan),速度快多了。

顺序扫描和索引扫描对比

  • 顺序扫描(Seq Scan):

    • PostgreSQL会读表里的每一行,检查查询条件,返回符合的行。
    • 如果没有索引,或者查询覆盖了几乎所有行,就会用这个。
  • 索引扫描(Index Scan):

    • PostgreSQL用索引先找到符合条件的行,然后只去表里查这些行。
    • 对于大表,如果只查一小部分数据,这种方式快很多。

举个例子: 没有索引时查找年龄

SELECT * FROM students WHERE age = 25;

可能要读100万行。有了B-TREE索引,比如只需要读100行。

索引结构对性能的影响

索引之所以快,是因为它们减少了需要扫描的数据量。比如表里有几百万行,索引能把它们组织起来,让查询只需要读几个节点,而不是全表。

理解索引结构很重要。知道索引怎么工作,能帮你搞清楚为什么有些查询慢,以及怎么让它们变快。

还有,选对索引类型也很关键。查区间用B-TREE。查数组或JSONB用GIN。选错索引反而会拖慢数据库。

实际例子

来看看索引在实际工作中怎么帮我们。

排序用的索引

CREATE INDEX salary_idx ON employees (salary);
SELECT * FROM employees ORDER BY salary;

有了B-TREE索引,PostgreSQL可以直接从索引里返回排好序的数据,不用再额外排序。

区间用的索引

CREATE INDEX price_idx ON products (price);
SELECT * FROM products WHERE price BETWEEN 100 AND 500;

B-TREE索引能很快找到落在指定区间的行。

常见问题和坑

为什么不是所有地方都该用索引? 索引会占用磁盘空间,而且会拖慢插入、更新和删除操作,因为每次都要更新索引结构。所以只给常用的列建索引才划算。

什么时候索引没用? 如果查询覆盖了表的大部分(比如WHERE true),PostgreSQL会选Seq Scan,因为读索引节点没啥优势。

1
调查/小测验
索引入门第 37 级,课程 4
不可用
索引入门
索引入门
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION