Postgres - "not exists" 比加入慢吗?

Postgres - Is "not exists" slower than join?

我正在尝试找出造成 3 table 秒的缓慢查询的原因,记录范围从几十万到几百万

版本

当前查询

select count(*) as aggregate
from "tango"
where "lima" = juliet
  and not exists(select 1
                 from "three_romeo" quebec_seven_oscar
                 where quebec_seven_oscar.six_two = tango.six_two
                   and quebec_seven_oscar."romeo" >= six_seven
                   and quebec_seven_oscar."three_seven" in
                       ('partial_survey', 'survey_completed', 'wrong_number', 'moved'))
  and ("mike" <= '2021-02-03 13:26:22' or "mike" is null)
  and not exists(select 1
                 from "kilo_golf" as "delta"
                 where "delta"."to" = tango.six_two
                   and "two" = november
                   and "delta"."romeo" >= '2021-02-05 13:49:15')
  and not exists(select 1
                 from "three_romeo" as "four"
                 where "four".foxtrot = tango.quebec_seven_victor
                   and "four"."three_seven" in ('deceased', 'block_calls', 'block_all'))
  and "tango"."yankee" is null;

这是查询在其当前状态下的分析 - https://explain.depesz.com/s/Di51

感觉有问题的地方在tangotable

读完另一本 post () 后尝试删除 or "mike" is null,这很有帮助

https://explain.depesz.com/s/XgmB

我是否应该尝试删除不存在以支持使用联接?

谢谢

我认为使用显式连接对您没有帮助,因为 PostgreSQL 无论如何都会将 NOT EXISTS 转换为反连接。

但是您发现了问题:是 OR。我建议您使用动态查询:仅当 mike 不为 NULL 时才添加条件,而不是使用 OR.

进行静态查询

您正在计算大约 600 万行,这需要一些时间。删除 or "mike" is null 有很大帮助的原因是它不再需要计算 mike 为空的行,这是其中的绝大多数。

但如果您确实需要计算这些行,这对您没有用。你也是?我很难想象这样一种情况,在这种情况下,您经常需要 600 万行的精确计数,以至于等待 4 秒是一个问题。