Postgres - "not exists" 比加入慢吗?
Postgres - Is "not exists" slower than join?
我正在尝试找出造成 3 table 秒的缓慢查询的原因,记录范围从几十万到几百万
- 探戈 - 6166101
- kilo_golf - 822805
- three_romeo - 535782
版本
- PostgreSQL 11.10
当前查询
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
感觉有问题的地方在tango
table
- tango.lima 在大多数记录(低基数)中等于 'juliet',我们目前没有此
的索引
- 长过滤器让我想知道我是否应该创建某种复合索引?
读完另一本 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 秒是一个问题。
我正在尝试找出造成 3 table 秒的缓慢查询的原因,记录范围从几十万到几百万
- 探戈 - 6166101
- kilo_golf - 822805
- three_romeo - 535782
版本
- PostgreSQL 11.10
当前查询
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
感觉有问题的地方在tango
table
- tango.lima 在大多数记录(低基数)中等于 'juliet',我们目前没有此 的索引
- 长过滤器让我想知道我是否应该创建某种复合索引?
读完另一本 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 秒是一个问题。