SQL服务器替代OR的条件

时间:2016-02-26 12:22:55

标签: sql sql-server

SELECT DISTINCT c.ID FROM tbl_Case c INNER JOIN
tbl_RequestBaseRequest b ON CaseId = c.ID
WHERE AreCalculationsCompleted = 0
AND b.IsApplicantRequest = 1
and c.IsArchived=0
AND (b.ID IN (SELECT DISTINCT ClientRequestId FROM tbl_Response)
OR b.OldClientRequestId IN (SELECT DISTINCT ClientRequestId FROM tbl_Response))
  

什么应该是OR的替代,这个OR正在进行此查询   真的很慢。

6 个答案:

答案 0 :(得分:3)

SELECT DISTINCT c.ID FROM tbl_Case c 
INNER JOIN tbl_RequestBaseRequest b ON CaseId = c.ID
WHERE AreCalculationsCompleted = 0
AND b.IsApplicantRequest = 1
and c.IsArchived=0
AND exists (SELECT 1 FROM tbl_Response t
  WHERE t.ClientRequestId = b.ID OR t.ClientRequestId = b.OldClientRequestId
)

答案 1 :(得分:3)

SELECT DISTINCT c.id
FROM tbl_Case c
JOIN tbl_RequestBaseRequest b ON CaseId = c.id
WHERE AreCalculationsCompleted = 0
    AND b.IsApplicantRequest = 1
    AND c.IsArchived = 0
    AND EXISTS(
        SELECT *
        FROM tbl_Response r
        WHERE r.ClientRequestId IN (b.id, b.OldClientRequestId)
    )

答案 2 :(得分:2)

您可以尝试删除distinct,并确保在tbl_Response(ClientRequestId)上有索引:

SELECT DISTINCT c.ID
FROM tbl_Case c INNER JOIN
     tbl_RequestBaseRequest b
     ON CaseId = c.ID
WHERE AreCalculationsCompleted = 0 AND
      b.IsApplicantRequest = 1 and
      c.IsArchived = 0 AND
      (b.ID IN (SELECT ClientRequestId FROM tbl_Response) OR
       b.OldClientRequestId IN (SELECT ClientRequestId FROM tbl_Response)
      );

其他索引可能有所帮助。此外,删除外部DISTINCT(如果没有必要也会提高性能)。其他索引可能有所帮助,但由于您没有合格AreCalculationsCompleted,因此无法指定。

答案 3 :(得分:2)

SELECT DISTINCT c.ID 
FROM tbl_Case c 
INNER JOIN tbl_RequestBaseRequest b ON CaseId = c.ID
INNER JOIN tbl_Response r ON (b.ID = r.ClientRequestId OR b.OldClientRequestId = r.ClientRequestId)

答案 4 :(得分:2)

SELECT DISTINCT c.ID 
FROM tbl_Case c 
    INNER JOIN tbl_RequestBaseRequest b 
        ON CaseId = c.ID
        AND AreCalculationsCompleted = 0
        AND b.IsApplicantRequest = 1
        AND c.IsArchived=0
        AND EXISTS (SELECT NULL 
                    FROM tbl_Response 
                    WHERE ClientRequestId IN (b.ID, b.OldClientRequestId))

答案 5 :(得分:1)

经常将OR改写为UNION有帮助。

SELECT c.ID
FROM   tbl_Case c
       INNER JOIN tbl_RequestBaseRequest b
               ON CaseId = c.ID
WHERE  AreCalculationsCompleted = 0
       AND b.IsApplicantRequest = 1
       AND c.IsArchived = 0
       AND b.ID IN (SELECT ClientRequestId
                    FROM   tbl_Response)
UNION
SELECT c.ID
FROM   tbl_Case c
       INNER JOIN tbl_RequestBaseRequest b
               ON CaseId = c.ID
WHERE  AreCalculationsCompleted = 0
       AND b.IsApplicantRequest = 1
       AND c.IsArchived = 0
       AND b.OldClientRequestId IN (SELECT ClientRequestId
                                    FROM   tbl_Response) 

你可以通过将c和b的连接封装到CTE中并在UNION的两个分支中引用它而不是重复它来进行整理,或者如果初始连接本身很昂贵,则可以实现临时表。