SQLite 提供 EXPLAIN
和 EXPLAIN QUERY PLAN
命令来帮助开发者查看 SQL 语句在执行前的“计划路径”。这对于性能优化、调试索引使用、理解查询逻辑都极其关键。掌握执行计划是提升 SQLite 查询效率的核心技能之一。
📚 目录
- EXPLAIN 与 EXPLAIN QUERY PLAN 的区别
- 为什么要查看执行计划?
- EXPLAIN QUERY PLAN 的输出解读
- 使用索引的判断依据
- 真实示例解析与优化
- 优化策略汇总
- 出站链接与站内推荐
- 参考资料
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. 📚 参考资料
- SQLite 官方 EQP 说明文档:https://sqlite.org/eqp.html
- 《高性能 SQLite 实战指南》
- SQLite 源码中的
vdbe.c
文件结构解析 - Stack Overflow 社区优化经验
- SQLite GitHub 官方仓库:https://github.com/sqlite/sqlite
✅ 下一篇将是 《SQLite Vacuum:空间回收与数据库瘦身》,我们将详解 VACUUM
命令的作用、风险、场景、自动化建议与替代方案。需要继续吗?
发表回复