SQL优化请求,分组依据,结果合并

时间:2013-01-24 16:30:57

标签: sql optimization plsql group-by

我想优化此SQL请求。我有一个大型数据库,并试图执行它,它花了7个小时。并且我无法使用SQL DEVELOPPER将结果导出到Excel。

请帮助我优化它并获得更好的响应时间。 这也是带给我的所有事件,我想通过che.ncp和che.typ使用“group by”表达式来合并它们,但它不起作用,因为我在select中有很多字段。

非常感谢你的宝贵帮助

select distinct 
   (select sum(che1.mon) 
    from awbeprod_fr.CHE_BKFRACOMC che1 
    where che.ncp = che1.ncp and
             che.typ = che1.typ and che.typ='T'),

   (select count(che1.typ) 
    from awbeprod_fr.CHE_BKFRACOMC che1 
    where che.ncp = che1.ncp 
    and che.typ=che1.typ and che.typ='T'),

   (select sum(che1.mon) 
    from awbeprod_fr.CHE_BKFRACOMC che1 
    where che.ncp = che1.ncp 
    and che.typ=che1.typ and che.typ='C'),

   (select count(che1.typ) 
    from awbeprod_fr.CHE_BKFRACOMC che1 
    where che.ncp = che1.ncp 
    and che.typ=che1.typ and che.typ='C'),

   che.ncp, che.mon, che.typ, che.dco, che.dag, 
   che.pie, m.cpro, m.age,  m.ribdec,  m.dev,
   p.lib, cli.cli, cli.lib, cli.pre, cli.nom, 
   adcli.adr1, adcli.adr2, adcli.adr3, adcli.cpos, adcli.ville
from 
   awbeprod_fr.CHE_BKFRACOMC che, awbeprod_fr.bkcom m, 
   awbeprod_fr.bkprod p, awbeprod_fr.bkcli cli, 
   awbeprod_fr.bkadcli adcli
where che.ncp = m.ncp 
and che.cli = m.cli and m.cli = cli.cli
and cli.cli = adcli.cli and m.cpro = p.cpro
order by che.ncp    

谢谢。

2 个答案:

答案 0 :(得分:3)

部分问题是您正在执行4个相关子查询以获得最终结果。我首先使用子查询来获得与此类似的sum()count()。这将获得CT的结果,然后您将其加入awbeprod_fr.CHE_BKFRACOMC

select 
  che1.sum_T,
  che1.count_T,
  che1.sum_C,
  che1.count_C,
  che.ncp, 
  che.mon, 
  che.typ, 
  che.dco, 
  che.dag, 
  che.pie,
  m.cpro,m.age, 
  m.ribdec, 
  m.dev,
  p.lib, 
  cli.cli, 
  cli.lib, 
  cli.pre, 
  cli.nom, 
  adcli.adr1, 
  adcli.adr2, 
  adcli.adr3, 
  adcli.cpos, 
  adcli.ville
from awbeprod_fr.CHE_BKFRACOMC che
inner join awbeprod_fr.bkcom m 
  on che.ncp = m.ncp 
  and che.cli = m.cli
inner join awbeprod_fr.bkcli cli
  on m.cli = cli.cli
inner join awbeprod_fr.bkadcli adcli
  on cli.cli = adcli.cli
inner join awbeprod_fr.bkprod p   
  on m.cpro = p.cpro
left join
(
  select typ, ncp,
    sum(case when typ='T' then mon else 0 end) sum_T,
    count(case when typ='T' then 1 else null end) count_T,
    sum(case when typ='C' then mon else 0 end) sum_C,
    count(case when typ='C' then 1 else null end) count_C
  from awbeprod_fr.CHE_BKFRACOMC
  group by typ, ncp
) che1
   on che.ncp = che1.ncp
   and che.typ=che1.typ
order by che.ncp  

答案 1 :(得分:1)

为清晰起见,请尝试将firs更改为显式JOIN。然后摆脱子查询,不需要它们:

SELECT  SUM(CASE WHEN che.typ = 'T' THEN che1.mon END) SumT,
        SUM(CASE WHEN che.typ = 'T' THEN 1 END) CountT,
        SUM(CASE WHEN che.typ = 'C' THEN che1.mon END) SumC,
        SUM(CASE WHEN che.typ = 'C' THEN 1 END) CountC,
        che.ncp, che.mon, che.typ, che.dco, che.dag, 
        che.pie, m.cpro, m.age,  m.ribdec,  m.dev,
        p.lib, cli.cli, cli.lib, cli.pre, cli.nom, 
        adcli.adr1, adcli.adr2, adcli.adr3, adcli.cpos, adcli.ville
FROM awbeprod_fr.CHE_BKFRACOMC che
INNER JOIN awbeprod_fr.bkcom m
    ON che.ncp = m.ncp AND che.cli = m.cli
INNER JOIN awbeprod_fr.bkprod p
    ON m.cpro = p.cpro
INNER JOIN awbeprod_fr.bkcli cli
    ON m.cli = cli.cli
INNER JOIN awbeprod_fr.bkadcli adcli
    ON cli.cli = adcli.cli
GROUP BY che.ncp, che.mon, che.typ, che.dco, che.dag, 
         che.pie, m.cpro, m.age,  m.ribdec,  m.dev,
         p.lib, cli.cli, cli.lib, cli.pre, cli.nom, 
         adcli.adr1, adcli.adr2, adcli.adr3, adcli.cpos, adcli.ville
ORDER BY che.ncp