2014-09-11 3 views
0

나는 T-SQL 쿼리 (SQL 서버 2,012분의 2,008)가 WHERE "부울"SQL 서버 :에서 하위 쿼리 다음과 같은 구조 사용하는 절

WHERE (@param1 IS NULL OR column1 = @param1) 
AND (@param2 IS NULL OR column2 = @param2) 
AND (@param3 IS NULL OR column3 = @param3) 

이것은 어떤을 최적화 자동으로 잘 작동 및 AND WHERE 절에서 NULL 매개 변수를 사용하여 부분을 수정했습니다.

WHERE 
    (@param1 IS NULL OR column1 IN (SELECT column 
            FROM table 
            WHERE column = @param1)) 
    AND (@param2 IS NULL OR column2 IN (SELECT column 
             FROM table 
             WHERE column = @param2)) 
    AND (@param3 IS NULL OR column3 IN (SELECT column 
             FROM table 
             WHERE column = @param3)) 

내 질문은 왜 최적화도 "IN"을 고려할 것입니다 : 나는 하위 쿼리와 함께이 같은 일을 수행 할 때

그러나, 옵티마이 저는 PARAM이 NULL 경우에도 여전히 하위 쿼리를 실행하기 위해 나타납니다 param이 NULL이라는 사실 때문에 쿼리의 일부가 이미 "단락되어"있어야합니다.

+0

내가 아는 한 SQL Server에는 '단락'이 없습니다. 'CASE'를 사용하여'short circuit' 동작을 얻을 수 있어야합니다. – cha

+0

내 [이 답변] (http://stackoverflow.com/questions/22978759/handling-select-condition-dynamically/22978868#22978868) 읽기 사례 – cha

+0

@cha의 사용 예 : 첫 번째 코드 예제가 예상대로 작동 함을 확신합니다. 나는 이것을 발명하지는 않았지만 얼마 동안 그것을 사용했고 실행 계획은 예상 된 행동을 증명한다. 두 번째 코드 예제도 작동하지만 실행 계획은 하위 쿼리가 아직 실행되고 있음을 보여줍니다. – eric

답변

0

@ user640466 : OPTION (RECOMPILE) 쿼리 힌트를 추가하면 나쁜 계획이 사라질 것입니다. 이유는 쿼리 최적화 프로그램이 IN 절을 평가하여 OPTION (재 컴파일)의 경우 ProductID 값을 가져야한다는 것입니다. 실행 시간 값을 감지 할 수 있습니다. Pls는 모험에서 작업 사본은 아래를 참조하십시오 작동 :

CREATE PROC MyTest 
@ProductID INT , 
@Name NVARCHAR(50), 
@ProductNumber NVARCHAR(50) 
AS 
SELECT * 
FROM Production.Product 
WHERE 
(ProductID IN (SELECT ProductID FROM Production.Product WHERE ProductID = @ProductID) OR @ProductID IS NULL) 
AND 
(Name IN (SELECT Name FROm Production.Product WHERE Name = @Name) OR @Name IS NULL) 
AND 
(ProductNumber IN (SELECT ProductNumber FROM Production.Product WHERE ProductNumber = @ProductNumber) OR @ProductNumber IS NULL) 
--OPTION (RECOMPILE) 
GO 

당신은 PROC 실행하면 : EXEC MYTEST 1, NULL을, 당신은 긴 계획은 그러나 SP를 변경하고 OPTION (RECOMPILE) 당신이 얻을 것이다 주석을 제거 얻을 것이다 NULL 좋은 계획.

+0

나는 그것을 실험 할 것이지만, 그렇더라도 옵티마이 저는 재 컴파일없이 서브 쿼리를 쉽게 피할 수있을 것 같다. 왜 OR 논리가 서브 쿼리의 결과를 무의미하게 만들면 서브 쿼리를 실행해야합니까? – eric