[译] SQLite 底层查询原理

2022-05-10 00:00:00 索引 查询 数据 遍历 排序

本文翻译自 Query Planning

目录

  1. 查询

    1.1 无索引表查询

    1.2 使用 rowid 查询

    1.3 使用索引查询

    1.4 多行内容查找

    1.5 使用 AND 链接多个 WHERE 条件查询

    1.6 多列查询

    1.7 覆盖索引查询

    1.8 使用 OR 链接多个 WHERE 条件查询

  2. 排序

    2.1 使用 rowid 排序

    2.2 使用索引排序

    2.3 覆盖索引排序

  3. 查询并排序

    3.1 通过多列索引查询并排序

    3.2 通过覆盖索引查询并排序

    3.3 通过索引进行局部排序

  4. 无 rowid 的表

概述

SQL 主要的特征 (在 所有 使用 SQL 语句的数据库中,不只是 SQLite)在于它是一中 表述式编程语言,而不是一种 过程化语言。在使用 SQL 时,你只需要告诉系统你想要计算什么,不需要描述如何去计算。计算结果的方式取决于 SQL 数据库引擎的内部查询规划器。

对于一条 SQL 语句,可能有成百上千种执行算法。所有的算法都可以计算出正确的结果,但是有的计算的快,有的计算的慢。查询规划器相当于一个 AI,为每条 SQL 语句尽可能规划快的执行算法。

多数情况下,查询规划器在 SQLite 中表现的十分出色。但是查询规划器需要使用索引进行协助。这些索引需要由开发者在设计数据库时加上。有时候,查询规划器会选择次优算法,而不是优的。这种情况下,需要开发者进行一些辅助操作来帮助查询规划器更好的工作。

这篇文章主要讲解了 SQLite 查询规划器和查询引擎背后的工作原理。有必要的时候,开发者可以根据这些原理更好地创建索引,帮助查询规划器高效地工作。

更多信息可以查看 SQLite query planner 和 next generation query planner.

1.查询

1.1 无索引表查询

在 SQLite 中,大多数表由一行或者多行组成,每一行都有一个独一无二的 key (rowid 或者 INTEGER PRIMARY KEY)(WITHOUT ROWID 表是一个特例)。这些数据通常会按照递增顺序排列。例如,这篇文章使用的表为 "FruitsForSale",主要存储了各种各样的水果以及水果的产地和价格信息。表结构如下:

CREATE TABLE FruitsForSale(
  Fruit TEXT,
  State TEXT,
  Price REAL
);
复制代码

写入一些数据之后,这张表将以 figure 1 图中所示的形式存储于磁盘中:

相关文章