对于大量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秒,快了几百倍!

时间: 2024-08-07 16:58:36

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

LEFT JOIN 多表查询的应用

表结构如下:只把主要字段列出 表一:付款记录表  Gather 字段:GatherID , AccountID, PayMents 金额, PayWay  付款方式 1 现金 2 刷卡 表2:销售记录表 Account 字段:AccountID 仓库:StorageID 时间:BeginTime   销售时间 表3:仓库表 Storage 字段 StorageID StorageName 现要求查出某个仓库某给时间段 总营业收入,现金收入,刷卡收入 SQL语句如下: SELECT S.Stora

Django ORM queryset object 解释(子查询和join连表查询的结果)

#下面两种是基于QuerySet查询 也就是说SQL中用的jion连表的方式查询books = models.UserInfo.objects.all() print(type(books)) ---> <class 'django.db.models.query.QuerySet'> 查询出来是一个对象QuerySey 取值 print(books.values()) books = models.UserInfo.objects.filter()print(type(books))

inner join 多表查询

三表以及三表以上联合查询: select table1.ziduan1,table2.ziduan,2,table3,ziduan3 from table1 inner join table2 on table1.field1 = table2.field1 inner join table3 on table1.field1 = table3.field1 举例: select clFile.FILEPATH,clPerson.personcode,cailiao.clcode from cl

【cl】多表查询(内、外连接)

交叉连接(cross join):该连接产生的结果集笛卡尔积 a有7行,b有8行    a的第一行与b的每一行进行连接,就有8条a得第一行 7*8=56条 select a.real_name,s.unix_host,s.os_username from account a cross  join service s:(56条) select a.real_name,s.unix_host,s.os_username from account a cross  join service s wh

SQL Fundamentals || 多表查询(内连接,外连接(LEFT|RIGHT|FULL OUTER JOIN),自身关联,ON,USING,集合运算UNION)

一.多表查询基本语法 在进行多表连接查询的时候,由于数据库内部的处理机制,会产生一些“无用”的数据,而这些数据就称为笛卡尔积. 多表查询时可以利用等值关联字段消除笛卡尔积 多表查询之中,每当增加一个关联表都需要设置消除笛卡尔积的条件 分析过程很重要: 确定所需要的数据表 确定已知的关联字段: 按照SQL语句的执行步骤编写:FROM,WHERE,SELECT,ORDER BY (由于SELECT是在WHERE子句之后执行,所以SELECT子句所定义的别名WHERE不可以直接使用) (由于SELEC

SQL数据库的多表查询

多表查询分为 内.外连接 外连接分为左连接(left join 或left outer join).右连接(right join 或者 right outer join).和完整外部连接 (full join 或者 full outer join) 左连接(left join 或 left outer join)的结果就是left join子句中的左表的所有行,而不仅仅是链接列所匹配的行,如果左表中的某行在右表中没有匹配,则在相关联的结果行中右表的所有选择列均为空值(NULL) SQL语法 se

IT十八掌 Mysql 多表查询

多表查询   多表设计--外键约束 作用:保证数据的完整性 创建完语句后,可以直接使用修改语句定义 alter table 表名 add foreign key 当前表名 (字段名) references 目标表名 (目标表的主键); 分析: 有一个部门的表,还有一个员工表, create database day16; use day16; create table dept( did int primary key auto_increment, dname varchar(30) ); c

Oracle 多表查询(1)

一.基本概念 多表查询的语法如下: SELECT [DISTINCT] * | 字段 [别名] [,字段 [别名] ,-]FROM 表名称 [别名], [表名称 [别名] ,-][WHERE 条件(S)][ORDER BY 排序字段 [ASC|DESC] [,排序字段 [ASC|DESC] ,-]]; 但是如果要进行多表查询之前,首先必须先查询出几个数据 -- 雇员表和部门表中的数据量,这个操作可以通过COUNT()函数完成. 范例:查询emp表中的数据量 --返回了14条记录 SELECT C

THINKPHP 中关联查询(多表查询)

THINKPHP 中关联查询(多表查询)可以使用 table() 方法或和join方法,请看示例: 1.Table方法:定义要操作的数据表名称,可以动态改变当前操作的数据表名称,需要写数据表的全名,包含前缀,可以使用别名,例如: $Model->Table('think_user user') ->where('status>1') ->select(); $Model->table('think_blog blog,think_type type')->where('