作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我发现 IN 和 NOT IN 令人惊讶(至少对我而言)。当我尝试解释对 PostgreSQL 数据库的第一个查询时:
EXPLAIN DELETE
FROM AuditTaskImpl l
WHERE l.processInstanceId in (select spl.processInstanceId
FROM ProcessInstanceLog spl
WHERE spl.status not in ( 2, 3))
它告诉我:
Delete on audittaskimpl l (cost=2794.48..6373.52 rows=50859 width=12)
-> Hash Semi Join (cost=2794.48..6373.52 rows=50859 width=12)
Hash Cond: (l.processinstanceid = spl.processinstanceid)
-> Seq Scan on audittaskimpl l (cost=0.00..2005.59 rows=50859 width=14)
-> Hash (cost=1909.24..1909.24 rows=50899 width=14)
-> Seq Scan on processinstancelog spl (cost=0.00..1909.24 rows=50899 width=14)
Filter: (status <> ALL ('{2,3}'::integer[]))
然而,当我把 in 换成 not in 时,这只是一个否定:
EXPLAIN DELETE
FROM AuditTaskImpl l
WHERE l.processInstanceId NOT in (select spl.processInstanceId
FROM ProcessInstanceLog spl
WHERE spl.status not in ( 2, 3))
它告诉我:
Delete on audittaskimpl l (cost=0.00..63321079.15 rows=25430 width=6)
-> Seq Scan on audittaskimpl l (cost=0.00..63321079.15 rows=25430 width=6)
Filter: (NOT (SubPlan 1))
SubPlan 1
-> Materialize (cost=0.00..2362.73 rows=50899 width=8)
-> Seq Scan on processinstancelog spl (cost=0.00..1909.24 rows=50899 width=8)
Filter: (status <> ALL ('{2,3}'::integer[]))
如您所见,对于 IN,它使用散列连接,这当然要快得多,但对于 NOT IN,它仅使用简单的逐行顺序扫描。但是由于 NOT IN 只是一个否定,它可以再次使用哈希连接并做相反的事情:当嵌套选择中有 processInstanceId 时使用 IN,将其添加到结果中,如果没有,则不添加它,使用 NOT IN嵌套select中有processInstanceId时,不添加到结果中,没有时,添加到结果中。
那么您能解释一下为什么会这样吗?为了澄清 AuditTaskImpl 具有 processInstanceId 属性,该属性也存在于 ProcessInstanceLog 表中,尽管它们之间没有外键关系。
谢谢。
最佳答案
NOT IN
的语义要求如果子查询中的任何值为NULL
,则返回nothing。因此,Postgres 需要查看所有值。
我强烈建议不要对子查询使用 NOT IN
。 始终使用NOT EXISTS
:
DELETE FROM AuditTaskImpl l
WHERE NOT EXISTS (SELECT 1
FROM ProcessInstanceLog spl
WHERE l.processInstanceId = spl.spl.processInstanceId AND
spl.status not in (2, 3)
);
关于sql - 为什么在 SQL 查询中 NOT IN 比 IN 慢很多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49701128/
我是一名优秀的程序员,十分优秀!