SQL中不存在替代方式

时间:2016-06-27 19:45:24

标签: sql sql-server sql-server-2008

我使用下面的查询需要很长时间才能执行,因为它有200万条记录

DELETE  
AC 
FROM 
SGT_APPLICATION_CHECKLIST AC
INNER JOIN SGT_APPLICATION_CHECKLIST_REF CR ON        AC.CHECKLIST_REF_ID   =      CR.CHECKLIST_REF_ID 
INNER JOIN SGT_APPLICATION APP ON APP.APPLICATION_ID = AC.APPLICATION_ID
WHERE 
NOT EXISTS
(
SELECT 1 FROM SGT_APPLICATION_CHECKLIST SAC
WHERE SAC.APPLICATION_ID = AC.APPLICATION_ID AND
APP.APP_CATEGORY_VALUE = CR.APP_CATEGORY_VALUE
AND APP.APP_SUB_CATEGORY_VALUE = CR.APP_SUB_CATEGORY_VALUE
)

那么替代方式是什么?#34;不存在"

3 个答案:

答案 0 :(得分:0)

您可以尝试使用LEFT JOIN

--DELETE AC 
SELECT * -- So you can quickly copy&paste to try. :)
FROM 
SGT_APPLICATION_CHECKLIST AC
INNER JOIN SGT_APPLICATION_CHECKLIST_REF CR ON AC.CHECKLIST_REF_ID = CR.CHECKLIST_REF_ID 
INNER JOIN SGT_APPLICATION APP ON APP.APPLICATION_ID = AC.APPLICATION_ID AND APP.APP_CATEGORY_VALUE = CR.APP_CATEGORY_VALUE AND APP.APP_SUB_CATEGORY_VALUE = CR.APP_SUB_CATEGORY_VALUE
LEFT JOIN SGT_APPLICATION_CHECKLIST SAC ON SAC.APPLICATION_ID = AC.APPLICATION_ID 
WHERE SAC.APPLICATION_ID IS NULL

虽然理论上不是EXISTS似乎是the best option

但是为什么你把这些条件放在子查询中的APP和CR之间呢?我将它们移动到相应的INNER JOIN,但您必须验证它是否有效。

答案 1 :(得分:0)

我敢打赌,在这种情况下,左外连接将比Exists更高效。

DELETE  
    AC 
    FROM 
    SGT_APPLICATION_CHECKLIST AC
    INNER JOIN SGT_APPLICATION_CHECKLIST_REF CR ON        AC.CHECKLIST_REF_ID   =      CR.CHECKLIST_REF_ID 
    INNER JOIN SGT_APPLICATION APP ON APP.APPLICATION_ID = AC.APPLICATION_ID
    LEFT OUTER JOIN SGT_APPLICATION_CHECKLIST CR2 ON CR2.APPLICATION_ID = AC.APPLICATION_ID AND APP.APP_CATEGORY_VALUE = CR2.APP_CATEGORY_VALUE AND APP.APP_SUB_CATEGORY_VALUE = CR2.APP_SUB_CATEGORY_VALUE
    WHERE 
    NOT CR2.APPLICATION_ID IS NULL

答案 2 :(得分:0)

首先移动条件 APP.APP_CATEGORY_VALUE = CR.APP_CATEGORY_VALUE 和APP.APP_SUB_CATEGORY_VALUE = CR.APP_SUB_CATEGORY_VALUE 超出子查询因为它们与该子查询无关。 你可以加入许多参数。

Join .... on A = B AND C = D

现在,关于你的问题,假设你已经清理了子查询 这样做

select/delete .... 
FROM 
SGT_APPLICATION_CHECKLIST AC
INNER JOIN SGT_APPLICATION_CHECKLIST_REF CR ON        AC.CHECKLIST_REF_ID   =      CR.CHECKLIST_REF_ID 
INNER JOIN SGT_APPLICATION APP ON APP.APPLICATION_ID = AC.APPLICATION_ID
.... other joins and changes i mentioned, etc...
LEFT JOIN SGT_APPLICATION_CHECKLIST as SAC 
ON SAC.APPLICATION_ID = AC.APPLICATION_ID
where SAC.APPLICATION_ID IS NOT NULL

仅获取与您的SAC加入的记录。