【问题标题】:Reduce the Execution time for a Postgres SQL减少 Postgres SQL 的执行时间
【发布时间】: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


【解决方案1】:

您的查询看起来像您尝试获取 id 为 1234 的模型,但不是 ids 123&1122。

那些可能会返回相同的结果:

select 
   m.mdl, m.src
from model m
join company c on c.name = m.name
  and c.partner = m.partner
where m.status = 'ACTIVE'
group by m.mdl, m.src
having count(case when c.id = 1234 then 1 end) = 1        -- 1234 exists
   and count(case when c.id in (123,1122) then 1 end) = 0 -- but not 123 or 1122

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'
AND NOT EXISTS
 ( select 1
    from company c
    where c.name = m.name
    and c.partner = m.partner 
    and c.id in (123,1122)
 ) 

【讨论】:

  • @dneoth 查询应该检索 id 为 1234 的 models 和 source 的组合,而不是 ids 123&1122。不幸的是,对于这种组合,上述 SQL 没有检索到正确的结果,在创建最终版本之前,我已经尝试了上面提到的第二个版本,但看起来我们在那里遗漏了一些东西。感谢大家抽出宝贵时间检查此内容。
猜你喜欢
  • 2012-12-31
  • 1970-01-01
  • 1970-01-01
  • 2012-11-09
  • 2018-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多