【发布时间】:2018-09-30 08:22:04
【问题描述】:
我一直在研究一个非常适合 MS-SQL 的 CTE。我正在将它翻译成 Oracle 并且它可以工作。但是它非常慢,当我查看解释计划时,我在运行查询时看到“合并加入笛卡尔”。我正在针对 Oracle 12.2 运行。如果我删除
“或”(...)
部分查询速度显着提高。然而,“合并加入笛卡尔”仍然出现在解释计划中。我已经确定了查询中的问题所在。
“和”(....)“或”(...)
在递归查询中是缓慢的根源。我需要这两个部分,因为有不同的路径,所以摆脱一个或另一个并不是一个真正的选择。我试图重写 CTE 的那部分,但我运气不佳。我的第一次尝试是在递归部分中包含第二个查询。然而,Oracle 只允许在 CTE 的递归部分进行一个查询。我也试图把它分解成更小的部分,但我的尝试失败了。对于重写此 CTE 中的递归部分的任何建议,我将不胜感激。
AND
(
myCTE3.SubWorkflowBaseId <> '0000000000000000'
and myCTE3.SubWorkflowBaseId is not null
and myCTE3.JoinColumn = wfb.WorkflowBaseId
and wfb.RevOfRcdId = wf.WorkflowId
and wf.workflowid = wfs.WorkflowId
)
OR
(
myCTE3.SubWorkflowId <> '0000000000000000'
and myCTE3.SubWorkflowId is not null
and myCTE3.JoinColumn = wf.workflowid
--and wf.workflowid = wfs.SubWorkflowId
and wf.workflowid = wfs.WorkflowId
and wf.WorkflowBaseId = wfb.WorkflowBaseId
)
我已经在 SQLFiddle 上发布了我的 CTE 和示例数据。我忘记在最初的帖子中发布预期的结果。记录应返回的顺序如下。工作流程中有一些步骤指向子工作流程,但这些步骤应从结果中排除。
步骤 1a -> 步骤 2a -> 步骤 3a -> 步骤 3b -> 步骤 1c。
Plan hash value: 3402776882
------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 4074 | 76 (2)| 00:00:01 |
| 1 | SORT ORDER BY | | 2 | 4074 | 76 (2)| 00:00:01 |
|* 2 | VIEW | | 2 | 4074 | 75 (0)| 00:00:01 |
| 3 | UNION ALL (RECURSIVE WITH) BREADTH FIRST| | | | | |
|* 4 | HASH JOIN | | 1 | 119 | 6 (0)| 00:00:01 |
|* 5 | TABLE ACCESS FULL | WORKFLOWSTEP2 | 1 | 102 | 3 (0)| 00:00:01 |
|* 6 | TABLE ACCESS FULL | WORKFLOW2 | 1 | 17 | 3 (0)| 00:00:01 |
| 7 | NESTED LOOPS | | 1 | 2239 | 69 (0)| 00:00:01 |
| 8 | BUFFER SORT (REUSE) | | | | | |
| 9 | MERGE JOIN CARTESIAN | | 1 | 170 | 9 (0)| 00:00:01 |
| 10 | MERGE JOIN CARTESIAN | | 1 | 136 | 6 (0)| 00:00:01 |
| 11 | TABLE ACCESS FULL | WORKFLOWSTEP2 | 1 | 102 | 3 (0)| 00:00:01 |
| 12 | BUFFER SORT | | 3 | 102 | 3 (0)| 00:00:01 |
| 13 | TABLE ACCESS FULL | WORKFLOWBASE2 | 3 | 102 | 3 (0)| 00:00:01 |
| 14 | BUFFER SORT | | 3 | 102 | 6 (0)| 00:00:01 |
| 15 | TABLE ACCESS FULL | WORKFLOW2 | 3 | 102 | 3 (0)| 00:00:01 |
|* 16 | RECURSIVE WITH PUMP | | | | | |
------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("MYCTE3"."STEPTYPE"<>2)
4 - access("WF"."WORKFLOWID"="WFS"."WORKFLOWID")
5 - filter("WFS"."WORKFLOWID"='1100000000000000')
6 - filter("WF"."WORKFLOWID"='1100000000000000')
16 - filter("MYCTE3"."JOINCOLUMN" IS NOT NULL AND
"MYCTE3"."SUBWORKFLOWBASEID"<>'0000000000000000' AND "MYCTE3"."SUBWORKFLOWBASEID" IS NOT NULL AND
"MYCTE3"."JOINCOLUMN"="WFB"."WORKFLOWBASEID" AND "WFB"."REVOFRCDID"="WF"."WORKFLOWID" AND
"WF"."WORKFLOWID"="WFS"."WORKFLOWID" OR "MYCTE3"."SUBWORKFLOWID"<>'0000000000000000' AND
"MYCTE3"."SUBWORKFLOWID" IS NOT NULL AND "MYCTE3"."JOINCOLUMN"="WF"."WORKFLOWID" AND
"WF"."WORKFLOWID"="WFS"."WORKFLOWID" AND "WF"."WORKFLOWBASEID"="WFB"."WORKFLOWBASEID")
【问题讨论】:
标签: sql oracle common-table-expression