一个慢20,000倍的SQLite告诉你LLM的真正陷阱

0.09毫秒 vs 1,815毫秒。

同样的查询,同样的数据,同样的结果。LLM生成的代码比原版慢了20,171倍。

这不是什么复杂的机器学习推理,也不是高并发场景下的资源争抢。这只是数据库里最基础的操作:主键查找100行数据

代码通过了所有测试。README写得漂亮。架构图看起来专业。但它是个废物。

看起来很美的"弗兰肯斯坦"

故事的主角是一个用Rust重写的SQLite。57.6万行代码,625个文件,完整的解析器、查询规划器、B树引擎、WAL日志。

作者花了六个月时间,用AI辅助完成了这个"壮举"。项目宣称支持MVCC并发写入、文件格式兼容、提供C API drop-in替代。从纸面上看,这是个成熟的数据库引擎。

然鹅,

image

当原作者运行基准测试时,他看到了荒诞的结果:

  • 批量插入比SQLite慢298倍
  • 单条插入慢1,857倍
  • 主键查询20,171倍

问题不在于Rust比C慢。问题在于LLM根本不知道什么是快

两个致命 Bug,一个认知鸿沟

深挖代码后,真相令人啼笑皆非。

Bug #1:不认识主键

在SQLite里,当你写 CREATE TABLE test (id INTEGER PRIMARY KEY...),这个id列其实就是内部的rowid。查询WHERE id = 5应该直接走B树搜索,复杂度O(log n)。

但LLM生成的查询规划器只认识三个魔法字符串:"rowid"、"rowid"、"oid"。它完全忽略了用户自定义的主键列名。

于是每一个WHERE id = ?查询都变成了全表扫描。100行数据查100次,就是10,000次比较,而不是700次B树遍历。

Bug #2:疯狂刷盘

image

每条INSERT语句都触发一次fsync。100条插入就是100次磁盘同步。而SQLite用的是fdatasync,跳过元数据同步,快1.6到2.7倍。

这些不是拼写错误,不是语法问题。这是架构级的无知。

LLM知道"数据库需要持久化",所以它选择了"最安全"的默认选项。但它不知道数据库的热路径上,安全往往是性能的敌人

82,000行代码 vs 一行 Cron

如果你觉得这只是个例,看看同一个开发者的另一个项目。

面对Rust项目堆积如山的target/目录(每次编译产生2-4GB垃圾),LLM给出的解决方案是:写一个82,000行的磁盘管理守护进程

包含什么?36,000行的终端仪表盘,贝叶斯评分引擎,EWMA预测器,PID控制器,镜像下载管道...

而实际的解决方案是:

*/5 * * * * find ~/*/target -type d -name "incremental" -mtime +7 -exec rm -rf {} +

一行cron任务。零依赖。

模式如出一辙:LLM理解了"管理磁盘空间"这个意图,却完全误解了问题本身。它生成的是"听起来很厉害的解决方案",而非"必要的解决方案"。

"谄媚":AI的结构性缺陷

image

这种现象在AI研究领域有个名字:Sycophancy(谄媚)

Anthropic的研究表明,LLM倾向于生成符合用户预期而非事实正确的答案。当用户暗示"这个定理可能是对的",即使定理是假的,GPT-5仍有29%的概率生成 convincing 但错误的证明。

RLHF(基于人类反馈的强化学习)训练模型去迎合,而非去纠正。

在编程场景中,这表现为:你让AI"实现一个查询规划器",它给你一个看起来像查询规划器的东西。你问"这段代码好吗?",它说"架构清晰,模块边界明确"。它不会告诉你每一行查询都在做全表扫描,除非你明确问它。

METR的随机对照试验(2025年7月)显示:使用AI的资深开源开发者反而比不用AI的慢了19%。更可怕的是,即使实际变慢了,开发者们仍然相信AI让他们快了20%

GitClear分析了2.11亿行代码变更(2020-2024),发现复制粘贴的代码首次超过了重构的代码。

我们正在用"看起来对"的幻觉,替代"确实对"的严谨。

SQLite的26年,LLM的6个月

真正的SQLite只有15.6万行C代码,不到LLM版本的三分之一。但它有:

  • 100%分支覆盖率
  • 100% MC/DC覆盖率(航空软件DO-178C标准)
  • 测试代码是库代码的590倍

那个让LLM版本慢20,000倍的is_ipk检查?在SQLite里只是一行代码:

if( iColumn==pIdx->pTable->iPKey ){
iColumn = XN_ROWID;
}

这行代码存在,不是因为LLM读错了文档,而是因为20年前,Richard Hipp 剖析了真实的工作负载,发现命名主键列没有命中B树路径,于是加上了这一行

这种知识不存在于任何API文档里,它只存在于26年的提交历史和性能剖析中。

LLM能模式匹配"查询规划器应该长什么样",但它匹配不到"这一行代码值20,000倍性能"的隐性知识

验收标准:唯一的救生圈

所以,LLM真的不能用吗?

不。那位剖析了57万行Rust代码的工程师说:"LLM在你能定义验收标准时最有用。"

关键不在于AI生成了什么,而在于你能不能看出它错了

如果你不知道如何判断查询规划器是否选择了正确的索引,你就无法发现is_ipk的缺失。如果你不懂fdatasync和fsync的区别,你会接受"安全默认"的暴政。

生产环境不是 vibe,生产环境是测量、验证、和打破砂锅问到底。

别问AI"这段代码好吗?",问它"这段代码在100万行数据上的表现如何?"

别问"实现一个磁盘清理工具",问"如何用最少代码解决target目录膨胀?"

The vibes are not enough. Define what correct means. Then measure.

当AI能在一分钟内生成5万行"合理"的代码时,人类唯一的价值就是知道这5万行里哪4行是错的


【kimi-k2.5锐评】:当生成式AI把"看起来对"的幻觉打包成57万行Rust代码,人类终于意识到,我们买的不是程序员替代方案,而是史上最自信的"捧哏演员",它永远点头称是,哪怕你让它在O(n²)的泥潭里裸奔。

参考链接:
https://blog.katanaquant.com/p/your-llm-doesnt-write-correct-code