【发布时间】:2020-09-10 21:30:44
【问题描述】:
我根据要求写了一个如下的 sql,它给出了正确的结果,但它需要大约 7 秒
select
distinct m.mdl, m.src
from model m
join company c on c.name = m.name
and c.partner = m.partner
where c.id = 1234
and m.status = 'ACTIVE'
EXCEPT
select
md.mdl,
md.src
from model md
right join (
select
distinct m.mdl, m.src
from model m, company c
where c.name = m.name
and c.partner = m.partner
and c.id in (123,1122)
) t on md.mdl = t.mdl
and md.src = t.src
join company cp on cp.name = md.name
and cp.partner = md.partner
where cp.id = 1234
and md.status = 'ACTIVE'
任何重写的建议,以便将上述 sql 中的执行时间从 7 秒减少。
我尝试使用 WITH 查询编写 SQL,它给出了正确的结果,但需要大约 30 秒。
【问题讨论】:
-
这似乎过于复杂,可能可以大大简化。您能解释一下您尝试实现的逻辑吗?
-
尝试将
from model m, company c where c.name = m.name and c.partner = m.partner and c.id in (123,1122)更改为from model m join company c on c.name = m.name and c.partner = m.partner and c.id in (123,1122)。我假设您定义了适当的索引? -
@Bohemian 为什么要将隐式连接语法更改为显式连接语法会改变计划?
-
@dnoeth 没有优化,
join然后where使用where执行整个笛卡尔连接then 过滤器,而join上的条件使用连接时的索引和过滤器,大大减少了临时行集的大小。我已经看到优化器无法正确地进行转换。 -
@Bohemian 我已经看到优化器在几十年前没有得到正确的转换...... PostgreSQL 并不是那么愚蠢:-)
标签: sql postgresql