50字范文,内容丰富有趣,生活中的好帮手!
50字范文 > 笛卡尔乘积 oracle 【优化案例】一次笛卡尔乘积的优化

笛卡尔乘积 oracle 【优化案例】一次笛卡尔乘积的优化

时间:2021-09-09 18:14:52

相关推荐

笛卡尔乘积 oracle 【优化案例】一次笛卡尔乘积的优化

今天一个网友妹子发来一段SQL说执行非常慢,让我看下,其实问题很简单,2分钟搞定,我们平时也会经常遇到,SQL及执行计划如下--跑了7分钟

SELECTT.*,A.*,B.LOGIN_ID,B.USER_NAME

FROMMID.T_RPT_RES_PRO_PRE_ALL_LISTTEMPT,

KPICODE.ODS_CB_ORGAN_GRID_ALL_MVA,

KPI.PURE_USERB

WHERET.FIVE_LEVEL_OWN=B.LOGIN_ID

ANDB.USER_ORG=A.LEVEL_ID;

SELECTCOUNT(1)FROMMID.T_RPT_RES_PRO_PRE_ALL_LISTTEMPT;--4733

SELECTCOUNT(1)FROMKPICODE.ODS_CB_ORGAN_GRID_ALL_MVA;--16719

SELECTCOUNT(1)FROMKPI.PURE_USERB;--26497

执行计划

----------------------------------------------------------

Planhashvalue:136974

--------------------------------------------------------------------------------

-------------------------------

|Id|Operation|Name|Rows|

Bytes|Cost(%CPU)|Time|

--------------------------------------------------------------------------------

-------------------------------

|0|SELECTSTATEMENT||1|

1259|144(1)|00:00:02|

|1|NESTEDLOOPS||1|

1259|144(1)|00:00:02|

|2|MERGEJOINCARTESIAN||1|

1236|144(1)|00:00:02|

|3|TABLEACCESSFULL|T_RPT_RES_PRO_PRE_ALL_LISTTEMP|1|

1138|2(0)|00:00:01|

|4|BUFFERSORT||16690|

1597K|142(1)|00:00:02|

|5|MAT_VIEWACCESSFULL|ODS_CB_ORGAN_GRID_ALL_MV|16690|

1597K|142(1)|00:00:02|

|*6|TABLEACCESSBYINDEXROWID|PURE_USER|1|

23|0(0)|00:00:01|

|*7|INDEXUNIQUESCAN|UK_PURE_USER_LOGIN_ID|1|

|0(0)|00:00:01|

--------------------------------------------------------------------------------

-------------------------------

PredicateInformation(identifiedbyoperationid):

---------------------------------------------------

6-filter("B"."USER_ORG"="A"."LEVEL_ID")

7-access("T"."FIVE_LEVEL_OWN"="B"."LOGIN_ID")

统计信息

----------------------------------------------------------

1recursivecalls

0dbblockgets

177858134consistentgets

0physicalreads

0redosize

1436253bytessentviaSQL*Nettoclient

2157bytesreceivedviaSQL*Netfromclient

276SQL*Netroundtripsto/fromclient

1sorts(memory)

0sorts(disk)

4125rowsprocessed

可以看到2个表和一个物化视图关联,数据量都不大(几万条数据),却执行了7分钟,1.7亿的逻辑读!!

看下执行计划,ID=2的MERGEJOINCARTESIAN,

看到这个就基本明白怎么回事了,MERGEJOINCARTESIAN是笛卡尔乘积的意思,这样的一个SQL里为什么会出现笛卡尔积呢?

看下where条件FROMMID.T_RPT_RES_PRO_PRE_ALL_LISTTEMPT,

KPICODE.ODS_CB_ORGAN_GRID_ALL_MVA,

KPI.PURE_USERB

WHERET.FIVE_LEVEL_OWN=B.LOGIN_ID

ANDB.USER_ORG=A.LEVEL_ID;

3表关联T和B关联,然后B和A关联,没有漏关联条件,而走了笛卡尔积。我们可以看到是T表和A表做了笛卡尔积,再跟B表做了NL

然而关联条件确实T和B关联B和A关联,T和A并没有直接的关联关系,

所以可以看出这里CBO错误的评估让T和A没有关联关系的表先做了关联,当然产生了笛卡尔积,想解决这个问题也很简单,

加hint让执行计划按照我想要的路径走,use_hash(T,B,A)即可,改后秒出数据。

止于为什么Oracle会选择走这样的执行计划,可以说是Oracle的一个BUG,错误的评估导致了没有关联的表关联了起来。

有人说在10gR2版本此bug已经修复,但是仍旧经常出现这个问题,所以大家如果遇到此问题可以直接指定执行路径即可。

还有人说可以直接修改当前session禁用笛卡尔积,使用/*+OPT_PARAM('_optimizer_mjc_enabled','false')*/,于是我也让妹子试了试发现依旧很慢,

我看了下执行计划,执行计划中虽然去掉了笛卡尔积,但路径没有改变,依旧是T和A先关联,不过使用的是NL关联。所以依旧很慢

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。