网易首页 > 网易号 > 正文 申请入驻

SQLite把子查询拍扁了:1个优化让查询快3倍

0
分享至


SQLite处理聚合查询时,会先造一张临时表。这张表不存原始数据,只存每个分组的中间计算结果——COUNT累加到哪了,SUM算到多少了。等所有行扫完,再一次性输出最终结果。两阶段执行,避免重复扫描,这是数据库工程师二十年前的老手艺。

但子查询是另一回事。你写了个嵌套SELECT,数据库默认会怎么做?先执行内层,结果扔进临时表,外层再接着跑。问题在于:这张临时表没索引。外层想过滤、想关联,都得全表扫。数据被读两遍,IO翻倍。

SQLite的解法叫「子查询拍扁」(Subquery Flattening)。把嵌套结构拆平,合并成单层查询,一次扫描解决战斗。

举个例子。原查询:

SELECT a FROM (SELECT x + y AS a FROM t1 WHERE z < 100) WHERE a > 5;

拍扁后变成:

SELECT x + y AS a FROM t1 WHERE z < 100 AND a > 5;


条件直接下推,索引能用上了,临时表也不用建了。性能提升多少?取决于数据量和原查询复杂度,但少一次全表扫描是确定的收益。

拍扁不是万能药:SQLite的严格门槛

SQLite不会无脑拍扁。它列了一堆条件,满足才动手。比如:子查询不能用GROUP BY或DISTINCT,不能带LIMIT,不能是聚合查询,外层不能是LEFT JOIN的右表……规则很细,本质是在「优化收益」和「语义正确」之间走钢丝。

为什么LEFT JOIN的右表特殊?拍扁可能改变结果集的行数,LEFT JOIN对NULL的处理很敏感,乱优化会出Bug。SQLite选择保守:宁可不优化,不能算错。

视图(View)是子查询拍扁的最大受益者。你定义一个视图,每次引用它,底层都转成子查询。没有拍扁优化,视图就成了性能陷阱——多层嵌套,层层建临时表。拍扁之后,视图只是语法糖,执行计划跟手写JOIN没区别。

MIN/MAX的捷径:索引直接定位

聚合查询里,MIN和MAX是异类。SQLite对它们有特殊照顾:如果字段有索引,直接跳到最后一条(或第一条)记录,返回结果。不用扫全表,不用建临时表,O(1)复杂度。


这个优化依赖索引的物理有序性。B-Tree索引天然按值排序,MIN就是最左节点,MAX就是最右。SQLite的查询优化器会检查:有没有可用索引?查询是不是纯粹的MIN/MAX,没带GROUP BY或其他聚合?条件满足,直接走捷径。

但加个GROUP BY就失效。比如SELECT department, MIN(age) FROM employees GROUP BY department,必须按部门分组再求最小值,索引帮不上忙,老老实实走两阶段聚合。

从查询到字节码:前端最后一块拼图

到目前为止,SQLite的前端完成了:解析SQL文本,生成语法树,分析名字和类型,选择索引,优化JOIN顺序,拍扁子查询,规划聚合执行方式。下一步是生成字节码(Bytecode),交给虚拟机执行。

字节码是SQLite的IR(中间表示,Intermediate Representation)。跟LLVM的IR类似,但更简单、更贴近数据库操作——打开表、定位索引、比较值、跳转标签。前端做的所有优化,最终都体现在字节码的指令序列里。

作者Maneshwar在系列前文已经讲过索引选择和排序优化。这篇补上了聚合和子查询,SQLite查询引擎的前端逻辑基本完整。对开发者来说,理解这些机制有个实际好处:写SQL时,你能预判哪些写法会被优化,哪些会踩坑。

比如知道拍扁规则,就不会在视图里塞LIMIT还指望性能;知道MIN/MAX走索引,就会给高频查询字段加索引而不是全表缓存。数据库是黑箱,但箱子上有些缝隙,透进光来。

Maneshwar正在做git-lrc,一个基于AI的代码审查工具,每次提交自动跑。项目开源在GitHub,免费无限制。他写这个SQLite系列,部分动机是梳理自己工具里的SQL优化逻辑——审查代码时,也能指出潜在的数据库性能问题。

如果你用过类似工具,或者在自己项目里踩过子查询的性能坑,他的实现思路值得一看:把数据库知识编码成规则,让AI当 reviewer 的副驾驶。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
俄罗斯为啥罕见卖油给日本?欧佩克+宣布增产……

俄罗斯为啥罕见卖油给日本?欧佩克+宣布增产……

新民周刊
2026-05-04 13:05:22
48岁杨乐乐复出落泪,自曝与汪涵婚姻现状,倒霉事都让她赶上了

48岁杨乐乐复出落泪,自曝与汪涵婚姻现状,倒霉事都让她赶上了

大眼妹妹
2026-05-03 18:07:54
国足终于立功了,一把砍掉国际足联10个亿

国足终于立功了,一把砍掉国际足联10个亿

宝哥精彩赛事
2026-05-04 21:27:48
丰田世纪全新渲染图,日系顶级豪华太对味了

丰田世纪全新渲染图,日系顶级豪华太对味了

味健的汽车
2026-05-04 10:35:10
河南医院大洗牌!看病规矩全变了

河南医院大洗牌!看病规矩全变了

刘哥谈体育
2026-05-04 18:29:37
明后三天!湖南、江苏、东方卫视杀疯了,4部大剧同时开播, 追哪部

明后三天!湖南、江苏、东方卫视杀疯了,4部大剧同时开播, 追哪部

TVB的四小花
2026-05-04 22:12:14
允许一切,自在随心

允许一切,自在随心

青苹果sht
2026-05-04 05:03:52
行情彻底大变天,赶紧打消近期买车的念头。

行情彻底大变天,赶紧打消近期买车的念头。

流苏晚晴
2026-05-03 17:34:09
看了长假全网破防的“8万人集体自爆丑照”,我才顿悟什么是人生顶级心态!

看了长假全网破防的“8万人集体自爆丑照”,我才顿悟什么是人生顶级心态!

脆皮先生
2026-05-04 19:42:03
过气艺人有多可怜?五一沦落景区打工,有人无戏可拍,令人心酸

过气艺人有多可怜?五一沦落景区打工,有人无戏可拍,令人心酸

奇思妙想草叶君
2026-05-02 23:27:22
国家一级女演员陈丽云被逮捕!

国家一级女演员陈丽云被逮捕!

许三岁
2026-03-28 09:24:30
邓伯什升级附加赛出局,王博豪留洋首季出场19次送出1助攻

邓伯什升级附加赛出局,王博豪留洋首季出场19次送出1助攻

狗哥是一名内拉
2026-05-04 14:31:10
“见过最廉价的兜底”,一份山姆烧鸡,让低认知母子沦为全网笑柄

“见过最廉价的兜底”,一份山姆烧鸡,让低认知母子沦为全网笑柄

妍妍教育日记
2026-04-15 09:30:09
吃他汀不想肝损伤,记住4个时间、记住5不要,帮你避免肝脏受损

吃他汀不想肝损伤,记住4个时间、记住5不要,帮你避免肝脏受损

健康之光
2026-05-04 15:10:05
豆包又更新了!一键生成王炸PPT,10分钟搞定半天工作量!

豆包又更新了!一键生成王炸PPT,10分钟搞定半天工作量!

秋叶PPT
2026-05-03 08:22:37
绝色美人艾梅柏:曾经迷倒德普和马斯克,如今带着3个娃“隐居”

绝色美人艾梅柏:曾经迷倒德普和马斯克,如今带着3个娃“隐居”

小书生吃瓜
2026-05-02 22:22:47
荒唐的斯威士兰:集中10万少女贡献国王选妃,国民平均寿命35岁

荒唐的斯威士兰:集中10万少女贡献国王选妃,国民平均寿命35岁

春秋砚
2026-04-25 17:15:06
对越作战前,邓小平为何不顾兵家大忌,坚持换掉昆明军区司令员

对越作战前,邓小平为何不顾兵家大忌,坚持换掉昆明军区司令员

历史龙元阁
2026-05-02 10:55:21
今天开会,很多医生都担心5.1后被抓!

今天开会,很多医生都担心5.1后被抓!

一口娱乐
2026-05-04 05:47:58
许家印拿钱开路:5千万签女明星 送几十瓶茅台 没他搞不定的人?

许家印拿钱开路:5千万签女明星 送几十瓶茅台 没他搞不定的人?

念洲
2026-04-29 14:46:42
2026-05-04 22:59:00
码上闲叙
码上闲叙
有态度网友ytd
3233文章数 39关注度
往期回顾 全部

科技要闻

在中国市场搞「付费订阅」,豆包咋想的?

头条要闻

上科大39岁博导王晨辉为救孩子去世 同学发声

头条要闻

上科大39岁博导王晨辉为救孩子去世 同学发声

体育要闻

骑士破猛龙:加雷特·阿伦的活力

娱乐要闻

张敬轩还是站上了英皇25周年舞台

财经要闻

魔幻的韩国股市,父母给婴儿开户买股票

汽车要闻

同比大涨190% 方程豹4月销量29138台

态度原创

本地
艺术
家居
健康
军事航空

本地新闻

用青花瓷的方式,打开西溪湿地

艺术要闻

火灾后第17年,TVCC电视文化中心正式启用

家居要闻

灵动实用 生活艺术场

干细胞治烧烫伤面临这些“瓶颈”

军事要闻

特朗普回绝伊朗新方案

无障碍浏览 进入关怀版