Skip to content

SQLite - EXPLAIN

要理解 SQLite 如何执行查询,您可以在语句前加上 EXPLAIN QUERY PLAN 关键字。这是通过分析“查询计划”来调试慢查询和优化数据库性能不可或缺的工具。

虽然存在一个较低级别的 EXPLAIN 命令(显示虚拟机操作码),但 EXPLAIN QUERY PLAN 提供了一个高级的、人类可读的查询执行策略描述,这对于应用程序开发者来说更为实用。

EXPLAIN QUERY PLAN [Your SQLite Query];

输出描述了 SQLite 将要执行的步骤。关键是查找在大表上可能效率低下的操作:

  • SCAN TABLE table_name:这表示一次全表扫描。SQLite 必须读取表中的每一行来查找与您的 WHERE 子句匹配的行。对于大表来说,这可能非常慢。
  • SEARCH TABLE table_name USING INDEX index_name:这很好!这意味着 SQLite 正在使用索引快速查找相关行,而无需扫描整个表。
  • SEARCH TABLE table_name USING COVERING INDEX index_name:这甚至更好。这意味着索引本身包含了查询所需的所有列,因此 SQLite 甚至不需要访问表数据,从而实现最大性能。

让我们使用 COMPANY 表并分析一个查询,以查找具有特定薪水的员工。

-- 示例表
-- CREATE TABLE COMPANY(ID INT, NAME TEXT, AGE INT, SALARY REAL);
-- 分析没有索引的查询
EXPLAIN QUERY PLAN SELECT NAME, AGE FROM COMPANY WHERE SALARY = 65000.0;

由于 SALARY 列上没有索引,初始输出将显示全表扫描:

-- 示例输出(详情可能有所不同)
-- selectid | order | from | detail
-- ---------|-------|------|-------------------
-- 0 | 0 | 0 | SCAN TABLE COMPANY

这是低效的。让我们通过在 SALARY 列上添加索引并再次运行分析来解决这个问题。

-- 步骤 1:创建一个索引以加快薪水查找
CREATE INDEX idx_company_salary ON COMPANY(SALARY);
-- 步骤 2:再次分析相同的查询
EXPLAIN QUERY PLAN SELECT NAME, AGE FROM COMPANY WHERE SALARY = 65000.0;

现在,查询计划显示 SQLite 使用了我们的新索引,这大大加快了速度。

-- 示例优化输出
-- selectid | order | from | detail
-- ---------|-------|------|-----------------------------------------------------
-- 0 | 0 | 0 | SEARCH TABLE COMPANY USING INDEX idx_company_salary (SALARY=?)

为了自动化分析或与其他工具集成,您可以在 SQLite shell 中为查询添加 --json 选项,以 JSON 格式获取查询计划。

EXPLAIN QUERY PLAN SELECT NAME, AGE FROM COMPANY WHERE SALARY = 65000.0 --json;

这提供了查询计划的结构化、机器可读版本,对于高级开发和监控工作流来说,这是一个强大的功能。