暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 如何优化多个联接表的查询

askTom 2017-09-06
319

问题描述

嗨,汤姆,

我有这个查询的简化版本。我只想检查是否还有其他方法可以进一步优化查询,尤其是在子查询上。我仅限于SQL。

我认为这可以进一步优化的原因是有2个类似的子查询,我认为这会使资源和运行时间加倍。

select acc.accid from acc
where ( select count(distinct(trunc(datetime)))
        from accact
  join accupd on accupd.accupdid = accact.accactid
  join disp on disp.dispid = accupd.dispid
  where accact.accactid = acc.accid
  and accupd.dictionary = 12345
  and disp.flag = 'Y'
  and trunc(accact.datetime) between (trunc(sysdate) - 3) and trunc(sysdate) - 1) >= 3
and   ( select count(distinct(trunc(datetime)))
        from accact
  join accupd on accupd.accupdid = accact.accactid
  join disp on disp.dispid = accupd.dispid
  where accact.accactid = acc.accid
  and accupd.dictionary = 12345
  and disp.flag = 'N'
  and trunc(accact.datetime) between (trunc(sysdate) - 3) and trunc(sysdate) - 1) = 0
;


谢谢

专家解答

必须使用相同联接的子查询不一定会使运行时增加一倍。这取决于他们处理的数据、可用的索引等。

但是,如果您只能访问一次表,则不太可能执行得更好!

在我看来,你可以通过以下方式做到这一点:

-将所有表格连接在一起
-按acc.accid和disp.flag分组
-添加having子句以根据标志值过滤计数是否返回正确的值

例如:

select acc.accid, disp.flag, count(distinct(trunc(datetime))) 
from acc
join accact 
on   accact.accactid = acc.accid 
join accupd on accupd.accupdid = accact.accactid 
join disp on disp.dispid = accupd.dispid 
where accupd.dictionary = 12345 
and trunc(accact.datetime) between (trunc(sysdate) - 3) and trunc(sysdate) - 1
and disp.flag in ('Y', 'N')
group  by acc.accid, disp.flag
having case when disp.flag = 'Y' then count(distinct(trunc(datetime))) end >= 3
and    case when disp.flag = 'N' then count(distinct(trunc(datetime))) end = 0

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论