对于大量left join 的表查询,可以在关键的 连接节点字段上创建索引。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对于大量left join 的表查询,可以在关键的 连接节点字段上创建索引。相关的知识,希望对你有一定的参考价值。

对于大量left join 的表查询,可以在关键的 连接节点字段上创建索引。

问题:

大量的left join 怎么优化
select a.id,a.num,b.num,b.pcs,c.num,
c.pcs,d.num,d.pcs,e.num,e.pcs,a.x,
a.y from a left join b.id=a.id and b.time=a.time
left join c.id=a.id and b.time=a.time
left join d.id=a.id and b.time=a.time
left join e.id=a.id and b.time=a.time
where a.time=2013-10-1
这样查询效率很低,要几十分钟才能出laugh数据~每张表有上千万条数据,求问该如何优化?

答案:

在各个表的id和time属性上创建索引,而且把其中除了第一次left join中的 b.time=a.time外,其余的 b.time=a.time去掉,并先对b表执行    b.time=2013-10-1的查询。
如果各表都需要判断时间的话,那么请先在各表上执行基于时间的选择操作,在参加左外连接。因此,时间字段上的索引很重要。

 

实例:自己实践经验:

select  --------------------------首先各个物料在各个期间的返利金额,然后根据每个期间求出对应每个月的返利总和-----------------------------------
    GZB.customer,GZB.company,GZB.jt,GZB.pz,
    sum(case GZB.qj when 01 then GZB.sl*GZB.fldj end) 一月,sum(case GZB.qj when 02 then GZB.sl*GZB.fldj end) 二月,
    sum(case GZB.qj when 03 then GZB.sl*GZB.fldj end) 三月,sum(case GZB.qj when 04 then GZB.sl*GZB.fldj end) 四月,
    sum(case GZB.qj when 05 then GZB.sl*GZB.fldj end) 五月,sum(case GZB.qj when 06 then GZB.sl*GZB.fldj end) 六月,
    sum(case GZB.qj when 07 then GZB.sl*GZB.fldj end) 七月,sum(case GZB.qj when 08 then GZB.sl*GZB.fldj end) 八月,
    sum(case GZB.qj when 09 then GZB.sl*GZB.fldj end) 九月,sum(case GZB.qj when 10 then GZB.sl*GZB.fldj end) 十月,
    sum(case GZB.qj when 11 then GZB.sl*GZB.fldj end) 十一月,sum(case GZB.qj when 12 then GZB.sl*GZB.fldj end) 十二月,cast(0 as number(20,8)),cast(0 as number(20,8))
    from 
    (        ----------------------------先把每个物料的返利单价,和对应的期间算出来------------------------
    select 
    wldw.lswldw_dwmc customer,dw.lsbzdw_dwmc company,org.organizationname jt,ms.materialsortname pz,
    gs.issfiscalperiod qj,nvl(gm.actoutquantity,0) sl,sum(NVL(gm.customfield34,0)+NVL(gm.customfield35,0)+NVL(gm.customfield36,0)+NVL(gm.customfield37,0)+NVL(gm.customfield38,0)+NVL(gm.customfield39,0)) fldj
    from goodsmovement gs
    left join goodsmovementitem gm on gs.goodsmovementid=gm.goodsmovementid
    left join lswldw wldw on wldw.lswldw_wldwbh=gs.customerid
    left join lsbzdw dw on dw.lsbzdw_dwbh=gs.isscompanyid
    left join organizations org on gs.issorgid=org.organizationid                       --生产机台
    left join materials m on m.materialid=gm.materialid
    left join materialsorts ms on ms.materialsortpath=substring(m.materialsortpath,0,12)
    where  gs.movetypeid=201 and substring(gs.createdate,0,4)=2016 and wldw.lswldw_wldwbh=09256
    and gs.issfiscalperiod between 01 and 12
    group by  wldw.lswldw_dwmc,dw.lsbzdw_dwmc,org.organizationname,ms.materialsortname ,
    gs.issfiscalperiod ,nvl(gm.actoutquantity,0)
    ) GZB 
    group by GZB.customer,GZB.company,GZB.jt,GZB.pz;

对于这段SQL,自己查询需要等待14秒出来结果。

但是给各表的关联字段上添加索引之后:

    create index gs_index on goodsmovement(goodsmovementid)
    create index gm_index on goodsmovementitem(goodsmovementid)
    create index gs_index1 on goodsmovement(customerid)
    create index gs_index2 on goodsmovement(isscompanyid)
    create index gs_index3 on goodsmovement(movetypeid)
    create index gs_index4 on goodsmovement(issorgid)
    
    create index dwbh on lswldw (lswldw_wldwbh)

查询速度大大提高:只需要0.17秒,快了几百倍!

以上是关于对于大量left join 的表查询,可以在关键的 连接节点字段上创建索引。的主要内容,如果未能解决你的问题,请参考以下文章

Sql_join left right

DQL查询数据----联表查询(left/right/inner join 区别)

DQL查询数据----联表查询(left/right/inner join 区别)

Left Join 查询返回错误结果

查询中的 LEFT JOIN 返回比预期更多的记录

使用 GROUP_CONCAT 进行 LEFT JOIN 的奇怪结果