SQL Server가 작성된대로 쿼리 조건을 실행하도록 하시겠습니까?


14

SQL Server 2008 R2를 사용하고 있으며이 의사 쿼리 (SP)가 있습니다.

select ...
from ...
WHERE    @LinkMode IS NULL
     AND (myColumn IN (...very long-running query...))
     ...
     ...

문제는 내가 SP를 실행하더라도 쿼리를 실행하는 데 시간이 오래 걸린다는 것입니다 @LinkMode=2.

알다시피, 장기 실행 쿼리는 @LinkMode가 null 인 경우에만 실행해야합니다. 여기서는 그렇지 않습니다. 내 경우에는 @LinkMode = 2!

그러나 내가 그것을 변경하면 :

 select ...
    from ...
    WHERE    1=2
         AND (myColumn IN (...very long time exeted query...))
     ...
     ...

SP 빠르게 실행됩니다.

전에는 최적화 프로그램이 기준 순서를 최적화 할 수 있다고 들었습니다 .

그래서 나는 묻습니다.

  • 옵티마이 저가 다른 경로를 선택하더라도 확인하는 것보다 빠를 수있는 것은 무엇 =null입니까? 내 말은, 다른 긴 쿼리를 실행하는 것보다 검사 if a==null훨씬 빠르다고 생각 합니다 ...

  • 어떻게 할 수 강제로 내가 (같은 순서로) 작성한으로 쿼리를 실행하는 SQL 서버를?

답변:


22

" Catch-All Query "트랩에 빠지게되는데 여기 Gail Shaw에 의해 잘 설명되어 있습니다 .

문제 요약 : SQL Server는 컴파일 후 쿼리 계획을 캐싱 한 다음 나중에 컴파일하기 전에 일치하는 쿼리 계획에 대해 캐시를 확인하여 쿼리 컴파일의 중요한 오버 헤드를 최적화합니다. 여기서 발생하는 "일치"는 순수한 텍스트이므로 변수의 실제 값은 이에 영향을 미치지 않습니다.

그건 좋은 시간의 99 %,하지만 어떤 경우에는 그것의 나쁜 . 나쁜 예는 누군가 C에서 단락 IF 문처럼 WHERE 절을 구성하려고 할 때입니다. SQL 컴파일러는 관계없이 작동하는 쿼리 계획을 하나 만들어야하기 때문에 제대로 작동하지 않습니다. WHERE 절에서 이러한 "영리한"논리적 스위칭 조건을 처리 할 수있는 유일한 방법은 전체 테이블을 스캔하고 행을 그대로 필터링하는 간단한 무차별 대입 계획을 세우는 것입니다. 색인을 활용하지 않고

놀랍지 않게, 이것은 파라미터 / 변수 값이 무엇이든 관계없이 균일하게 느리게 만듭니다.


8

SQL Server가 특정 순서로 절 조건을 실행하도록 보장 할 수있는 방법은 없습니다. 옵티마이 저는 항상 적절한 순서대로 평가합니다.

당신이 할 수있는 일은 다음과 같습니다 :

IF @LinkMode IS NULL
BEGIN
    select ...
    from ...
    WHERE (myColumn IN (...very long time exeted query...))
         ...
         ...
END
ELSE
BEGIN
    select ...
    from ...
    WHERE ...
         ...
END

3

옵션 인 경우 IF 문을 사용하여 적절한 형식의 쿼리를 실행하십시오. 또한 SQL에서는 DB 엔진에 수행 방법이 아니라 수행해야 할 작업을 지시합니다. 작업은 처음부터 끝까지 실행되지 않습니다. 정확히 무엇을할지 예측하기 어려울 수 있습니다. 당신은 아마 이것을 알고 있습니다;)


2

이 경우 쿼리 최적화 프로그램이 런타임에 실제 값을 가져와야하기 때문에 동적 SQL도 작동합니다 (잘못되면 수정하십시오. 실제로 확실하지 않지만 유사한 상황에서 사용하는 것을 기억하는 것 같습니다) . 그러나 IF / ELSE 절이 필요한 것을 정확하게 수행하는 가장 간단하고 쉬운 솔루션이기 때문에 IF / ELSE 절이 가장 적합하다는 점에서 다른 사람과 함께 있습니다.

아직 사용하지 않은 경우에 대비하여 나중에 참조 할 수 있도록 동적 SQL에 대한 실제 예제가있는 끔찍한 추악한 사이트는 다음과 같습니다. http://sqlusa.com/bestpractices/dynamicsql/


1

IF / ELSE 구문을 권장합니다. 어떤 이유로 든 효과가 없으면 WITH RECOMPILE 옵션을 사용하는 것이 좋습니다.


"if / else 구문"이 어떻게 보이는지 자세히 설명해 주시겠습니까? : D
jcolebrand

매번 이상적인 계획을 생성 할 수 있기 때문에 OPTION (WITH RECOMPILE)을 사용하는 것이 좋습니다. 컴파일 지연은 오버 헤드를 추가하지만이 경우 전체적으로 더 나은 것으로 생각됩니다.
SqlRyan 1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.