Oracle SQL查询SELECT MINUS SELECT不工作或太慢

时间:2014-09-12 11:51:22

标签: sql oracle

我不明白为什么以下Oracle 10g SQL查询无法正常工作,尽管每个子查询都能正常工作:

SELECT ref.EWO_ISSUE_ID, ref.EWO_REF_ID, ref.MSN_ID, ref.MSN, ref.HOV, ref.RANK, 
ref.EWO_WP_ID, ref.EWO_WP, ref.EPAC_TDU, ref.MOD, ref.MP, ref.EWO_REF_DESCRIPTION, 
ewo.EWO1, ewo.EWO2, ewo.EWO3, ref.TRS_ISSUE, ref.TRS_UPDATE_ON_SHEET_1, 
ref.TRS_UPDATE_ON_SHEET_2, ref.TRS_UPDATE_ON_SHEET_3,
ref.TRS_UPDATE_ON_SHEET_4, ref.TRS_UPDATE_ON_SHEET_5, ref.TRS_UPDATE_ON_SHEET_6,
ref.TRS_TECHDOM_INFO
FROM V_EWO_ACTUAL_REFERENCE ref
LEFT JOIN EWO_REFERENCE ewo
ON ref.EWO_REF_ID = ewo.EWO_REF_ID
WHERE ref.EWO_REF_ID IS NOT NULL
AND ref.TRS_TECHDOM_INFO IS NOT NULL

MINUS

SELECT EWO_ISSUE_ID, EWO_REF_ID, MSN_ID, MSN, HOV, RANK, EWO_WP_ID, EWO_WP,
EPAC_TDU, MOD, MP, EWO_REF_DESCRIPTION, EWO1, EWO2, EWO3, TRS_ISSUE,
TRS_UPDATE_ON_SHEET_1, TRS_UPDATE_ON_SHEET_2, TRS_UPDATE_ON_SHEET_3,
TRS_UPDATE_ON_SHEET_4, TRS_UPDATE_ON_SHEET_5, TRS_UPDATE_ON_SHEET_6,
TRS_TECHDOM_INFO
FROM EWO_REF_TRS_HISTORY;

我只收到超时错误,因为它需要很长时间。有谁知道什么可能是错的?

3 个答案:

答案 0 :(得分:2)

这可能无法解决您的问题,但可能会强制执行不同的执行计划:

with x as ( SELECT /*+ materialize */ ref.EWO_ISSUE_ID, ref.EWO_REF_ID, ref.MSN_ID, ref.MSN, ref.HOV, ref.RANK, 
                    ref.EWO_WP_ID, ref.EWO_WP, ref.EPAC_TDU, ref.MOD, ref.MP, ref.EWO_REF_DESCRIPTION, 
                    ewo.EWO1, ewo.EWO2, ewo.EWO3, ref.TRS_ISSUE, ref.TRS_UPDATE_ON_SHEET_1, 
                    ref.TRS_UPDATE_ON_SHEET_2, ref.TRS_UPDATE_ON_SHEET_3,
                    ref.TRS_UPDATE_ON_SHEET_4, ref.TRS_UPDATE_ON_SHEET_5, ref.TRS_UPDATE_ON_SHEET_6,
                    ref.TRS_TECHDOM_INFO
            FROM V_EWO_ACTUAL_REFERENCE ref
            LEFT JOIN EWO_REFERENCE ewo
            ON ref.EWO_REF_ID = ewo.EWO_REF_ID
            WHERE ref.EWO_REF_ID IS NOT NULL
            AND ref.TRS_TECHDOM_INFO IS NOT NULL ),
     y AS ( SELECT /*+ materialize */ EWO_ISSUE_ID, EWO_REF_ID, MSN_ID, MSN, HOV, RANK, EWO_WP_ID, EWO_WP,
                    EPAC_TDU, MOD, MP, EWO_REF_DESCRIPTION, EWO1, EWO2, EWO3, TRS_ISSUE,
                    TRS_UPDATE_ON_SHEET_1, TRS_UPDATE_ON_SHEET_2, TRS_UPDATE_ON_SHEET_3,
                    TRS_UPDATE_ON_SHEET_4, TRS_UPDATE_ON_SHEET_5, TRS_UPDATE_ON_SHEET_6,
                    TRS_TECHDOM_INFO
            FROM EWO_REF_TRS_HISTORY )
select *
from   x
minus
select *
from   y;

答案 1 :(得分:1)

你可以使用NOT EXISTS或NOT IN来检查这样的东西

SELECT ref.EWO_ISSUE_ID, ref.EWO_REF_ID, ref.MSN_ID, ref.MSN, ref.HOV, ref.RANK, 
  ref.EWO_WP_ID, ref.EWO_WP, ref.EPAC_TDU, ref.MOD, ref.MP, ref.EWO_REF_DESCRIPTION, 
  ewo.EWO1, ewo.EWO2, ewo.EWO3, ref.TRS_ISSUE, ref.TRS_UPDATE_ON_SHEET_1, 
  ref.TRS_UPDATE_ON_SHEET_2, ref.TRS_UPDATE_ON_SHEET_3,
  ref.TRS_UPDATE_ON_SHEET_4, ref.TRS_UPDATE_ON_SHEET_5, ref.TRS_UPDATE_ON_SHEET_6,
  ref.TRS_TECHDOM_INFO
FROM V_EWO_ACTUAL_REFERENCE ref
LEFT JOIN EWO_REFERENCE ewo
ON ref.EWO_REF_ID = ewo.EWO_REF_ID
WHERE ref.EWO_REF_ID IS NOT NULL
  AND ref.TRS_TECHDOM_INFO IS NOT NULL
  AND NOT EXISTS 
    (SELECT EWO_ISSUE_ID, EWO_REF_ID, MSN_ID, MSN, HOV, RANK, EWO_WP_ID, EWO_WP,
    EPAC_TDU, MOD, MP, EWO_REF_DESCRIPTION, EWO1, EWO2, EWO3, TRS_ISSUE,
    TRS_UPDATE_ON_SHEET_1, TRS_UPDATE_ON_SHEET_2, TRS_UPDATE_ON_SHEET_3,
    TRS_UPDATE_ON_SHEET_4, TRS_UPDATE_ON_SHEET_5, TRS_UPDATE_ON_SHEET_6,
T   RS_TECHDOM_INFO FROM EWO_REF_TRS_HISTORY);

或尝试使用NOT IN。希望它有所帮助。

答案 2 :(得分:0)

起初我认为第一个答案是正确的,但事实并非如此!第二个工作正常。我试着这样做似乎有效,但它比Jens的答案要慢得多。

SELECT columns
FROM V_EWO_ACTUAL_REFERENCE ref
LEFT JOIN EWO_REFERENCE ewo
ON ref.EWO_REF_ID = ewo.EWO_REF_ID
WHERE ...
AND ...
AND (...) NOT IN (SELECT columns FROM EWO_REF_TRS_HISTORY);

但最后我仍然对MINUS在查询我的问题时感到很困惑。