以下查询花费的时间太长(30秒)。 我认为瓶颈在where子句中。有可能优化吗?
SELECT
COUNT(*) AS IN_HELP
FROM
HCM.TableA
INNER JOIN
HCM.EMPLOYEE_POSITION_BOX EPB
ON
TableA.POSITION_BOX_CODE = EPB.POSITION_BOX_CODE AND NVL (V_DATE,SYSDATE) BETWEEN EPB.EFFECTIVE_DATE AND EPB.END_DATE
LEFT OUTER JOIN
HCM.NODE_LEVEL_MASTER NLM
ON
HCM.F_EMPLOYEE_ACTUAL_NODE(EPB.EMPLOYEE_CODE,TRUNC(SYSDATE)) = NLM.NODE_NO
LEFT JOIN
HCM.POSITION_STATUS_MASTER PSM
ON
TableA.STATUS = PSM.POSITION_STATUS_NO
WHERE
NLM.NODE_NO_LEVEL2 = V_LOOP.NODE_NO_LEVEL2
AND HCM.F_EMPLOYEE_ACTUAL_NODE(EPB.EMPLOYEE_CODE,TRUNC (SYSDATE)) <> TableA.NODE_NO
AND PSM.FLAG = 'Y'
AND TableA.STATUS <> '0108'
答案 0 :(得分:1)
首先,从WHERE
子句检查表的索引:
PSM.FLAG
不应该添加到索引中,因为它不会对表中的数据进行有效过滤。
另外,我是对的,HCM.F_EMPLOYEE_ACTUAL_NODE
是一个功能吗?如果是这样,那么您应该考虑将其从WHERE
子句中删除,因为执行计划不会检查内部查询,并且它根本没有被优化,这会导致性能问题。
答案 1 :(得分:1)
主要问题是您的功能HCM.F_EMPLOYEE_ACTUAL_NODE。首先将函数调用移到子查询(epbx):
SELECT
COUNT(*) AS IN_HELP
FROM
HCM.TableA
INNER JOIN
(SELECT HCM.F_EMPLOYEE_ACTUAL_NODE(EPB.EMPLOYEE_CODE,TRUNC(SYSDATE)) node, epb.* from HCM.EMPLOYEE_POSITION_BOX EPB) epbx
ON
TableA.POSITION_BOX_CODE = EPBx.POSITION_BOX_CODE AND NVL (V_DATE,SYSDATE) BETWEEN EPBx.EFFECTIVE_DATE AND EPBx.END_DATE
LEFT OUTER JOIN
HCM.NODE_LEVEL_MASTER NLM
ON
epbx.node = NLM.NODE_NO
LEFT JOIN
HCM.POSITION_STATUS_MASTER PSM
ON
TableA.STATUS = PSM.POSITION_STATUS_NO
WHERE
NLM.NODE_NO_LEVEL2 = V_LOOP.NODE_NO_LEVEL2
AND epbx.node <> TableA.NODE_NO
AND PSM.FLAG = 'Y'
AND TableA.STATUS <> '0108'
然后使用解释计划来确定您的查询是否有效写入。