SQLite 提供 EXPLAINEXPLAIN QUERY PLAN 命令来帮助开发者查看 SQL 语句在执行前的“计划路径”。这对于性能优化、调试索引使用、理解查询逻辑都极其关键。掌握执行计划是提升 SQLite 查询效率的核心技能之一。


📚 目录

  1. EXPLAIN 与 EXPLAIN QUERY PLAN 的区别
  2. 为什么要查看执行计划?
  3. EXPLAIN QUERY PLAN 的输出解读
  4. 使用索引的判断依据
  5. 真实示例解析与优化
  6. 优化策略汇总
  7. 出站链接与站内推荐
  8. 参考资料

1. EXPLAIN 与 EXPLAIN QUERY PLAN 的区别

命令描述输出形式
EXPLAIN显示 SQLite 虚拟机指令(虚拟机汇编级别)低级,复杂
EXPLAIN QUERY PLAN提供 SQL 查询的逻辑执行步骤(推荐使用)可读性强

示例:

EXPLAIN QUERY PLAN SELECT * FROM users WHERE id = 5;

输出类似于:

QUERY PLAN
--SEARCH TABLE users USING INTEGER PRIMARY KEY (rowid=?)

说明它使用了主键索引查询,而不是全表扫描。


2. 为什么要查看执行计划?

查看执行计划可以帮助你:

  • 发现查询是否在走索引
  • 判断查询是否存在“全表扫描”
  • 理解多表连接的顺序
  • 分析子查询或联合查询的执行顺序
  • 指导数据库设计、索引建立

3. EXPLAIN QUERY PLAN 的输出解读

一个典型的输出格式如下:

EXPLAIN QUERY PLAN SELECT name FROM users WHERE age > 30;

输出:

SCAN TABLE users

说明查询没有使用索引,进行了 全表扫描(SCAN)。

再来看一个带索引的:

CREATE INDEX idx_users_age ON users(age);
EXPLAIN QUERY PLAN SELECT name FROM users WHERE age > 30;

输出:

SEARCH TABLE users USING INDEX idx_users_age (age>?)

说明 成功使用索引,查询效率大大提升。


4. 使用索引的判断依据

执行计划中常见的关键词说明:

关键词说明
SCAN TABLE全表扫描,效率低
SEARCH TABLE ... USING INDEX使用索引,效率高
USING INTEGER PRIMARY KEY使用主键索引
USING COVERING INDEX使用覆盖索引(无需回表)
EXECUTE SCALAR SUBQUERY表示使用了子查询,需进一步分析

🔍 你可以借助这些输出判断是否需要添加或修改索引。


5. 真实示例解析与优化

示例:未使用索引

SELECT * FROM orders WHERE total_amount > 500;

输出:

SCAN TABLE orders

解决方案:

CREATE INDEX idx_orders_amount ON orders(total_amount);

再次查看:

EXPLAIN QUERY PLAN SELECT * FROM orders WHERE total_amount > 500;

输出:

SEARCH TABLE orders USING INDEX idx_orders_amount (total_amount>?)

性能明显提升。


6. 优化策略汇总

  • 避免 SELECT *:尽可能使用特定字段
  • 确保查询条件字段已建立索引
  • 多表 JOIN 时优先选择被驱动表索引
  • 使用 EXPLAIN 监控复杂查询结构
  • 子查询和临时表应提前优化或拆解
  • 考虑使用 COVERING INDEX 提高效率

7. 🔗 出站链接与站内推荐

外部参考

站内推荐文章


8. 📚 参考资料

  1. SQLite 官方 EQP 说明文档:https://sqlite.org/eqp.html
  2. 《高性能 SQLite 实战指南》
  3. SQLite 源码中的 vdbe.c 文件结构解析
  4. Stack Overflow 社区优化经验
  5. SQLite GitHub 官方仓库:https://github.com/sqlite/sqlite

✅ 下一篇将是 《SQLite Vacuum:空间回收与数据库瘦身》,我们将详解 VACUUM 命令的作用、风险、场景、自动化建议与替代方案。需要继续吗?