You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将含NOT IN子查询的SQL正确转换为适配大表的Peewee代码

正确Peewee实现方案

方案1:子查询写法(和你给出的原生SQL完全等价)

Peewee的not_in运算符原生支持传入Select查询对象,会直接生成嵌套子查询的SQL,不会将B表的查询结果拉取到应用内存,完全适配千万级数据量的场景。
你之前的写法只是存在括号配对的语法错误,导致生成的SQL不符合预期,所以返回结果和原生SQL不一致,修正后的代码如下:

# 写法1:直接调用count()方法
count = A.select().where(
    A.id.not_in(B.select(B.package_id).distinct())
).count()

# 写法2:手动指定COUNT函数,用scalar()拿结果,更直观
from peewee import fn
count = A.select(fn.COUNT('*')).where(
    A.id.not_in(B.select(B.package_id).distinct())
).scalar()

你可以通过print(A.select(...).sql())打印生成的SQL,验证和你写的原生SQL完全一致。

方案2:LEFT JOIN写法(部分数据库下性能更优)

LEFT JOIN + 空值判断的写法完全可以实现需求,对于很多数据库来说,这种写法的执行性能比NOT IN子查询更好,尤其是B表的package_id字段建有索引的情况下:

from peewee import fn

count = A.select(fn.COUNT(A.id)).join(
    B, on=(A.id == B.package_id), join_type='LEFT'
).where(B.package_id.is_null()).scalar()

这个写法的逻辑是左连接B表后,所有B表相关字段为空的记录就是A表中id不存在于B表package_id的记录,直接计数即可,同样不会有应用层的数据拉取开销。


内容的提问来源于stack exchange,提问作者Larytet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 19:00:01