oracle两张表进行关联的时候,只要不是特意去做,很难出现笛卡尔积的情况,但是多张关联的时候可就要小心了。即使你的条件中,表已经两两关联,但有些情况下还是可能会出现笛卡尔积的。
昨天有一个oracle的sql,都执行了6个月了,一直没有出现问题,可昨天就出现临时空间爆满的情况,查看报错的sql,然后在pl\sql里按F5,看了一下执行计划,发现竟然产生的笛卡尔积,真是郁闷的要死。
首先贴一下sql大家看一下
INSERT INTO DW_FORCAST_PROMOTION nologging SELECT PP.ID
PROM_ID,pp.Name PROM_NAME,w.Brand_Name,w.PRODUCT_ID,
TO_NUMBER(to_char(pp.TIMEBEGIN,'yyyymmdd')) TIME_BEGIN,
TO_NUMBER(to_char(pp.TIMEEND,'yyyymmdd')) TIME_END,100
prom_type
FROM
DWD.DWD_PM_PROMOTIONPACK pp,
DWD.DWD_PM_PROMOTIONPACKPRODUCT ppp,
DW_FORCAST_PRODUCT_INFO w
WHERE pp.Id
= ppp.IdPack
and
timebegin <= to_date('20120513 23:59:59','yyyymmdd
hh24:mi:ss') and timeend >=
to_date('20120513','yyyymmdd')
AND
ppp.IdProduct=w.PRODUCT_ID
and
pp.ischecked = 1
sql中3张表都是两两关联的,第一、二张表数据都是几十万,第三张表有700多W数据,之前运行的时候5秒就可以出结果,昨天突然2个小时都没出来。查看执行计划如下:
本来打算是第一张表跟第二张表先关联,然后跟第三张表关联的,可现在竟然成了第一张表跟第三张表关联,然后跟第二张表关联,由于第一张表跟第三张表没有关联字段,这样就产生了笛卡尔积,真是害苦了我。
既然发现了问题的所在,接下来修改问题就容易的多了,既然执行计划发生了变化,把执行计划按我们想要的来执行就可以了,当然有很多种解决方案,我的解决方案如下
加了一个hints,按顺序执行sql,哇,真是太给力了,4秒就出结果了,在看看执行计划怎么样
果然是按咱的执行计划执行的,看来半天没有白忙啊
由此可以看出,除了两张表关联外,其它多张表关联,都有可能发生风险,执行计划会改变,很可能会产生笛卡尔积或者索引等信息的修改。亲,以后一定要注意哦,小表笛卡尔积问题还不算大,数据量很大的话,很可能会发生杯具的哦,要不半天甚至几天都会令你头疼的
关于上面的 , 网上查一下就知道了,很容易的,有问题可以密我