2009-07-07 7 views
0

이 조건을 내 where 절의 일부로 사용하고 있습니다 : exists (select * from PRPB PB where PA.mid = PB.mid and (@inpo is null or PB.inpo = @inpo)) order by price.조건부 테스트를 추가 할 때 속도가 느립니다.

null이 아닌 값을 테스트하는 동안이 조건을 대신 사용하면 쿼리가 훨씬 빠르게 실행됩니다. exists (select * from PRPB PB where PA.mid = PB.mid and (PB.inpo = @inpo)) order by price. 이것이 무시할 수없는 속도 차이를 일으킨다는 것은 @inpo로 필터링할지 여부를 결정하기 위해 if 문과 함께 두 개의 별도 쿼리를 사용해야한다는 것을 의미합니다. 이것은 많은 코드 반복을 의미하기 때문에 나에게 나쁜 영향을 미친다.

상황은 내가 시도 :

  • 조금 만들기 그 @inpo가 null 그와 비교입니다 저장 여부를 지정합니다.
  • 무효성 검사를 exist 문 왼쪽으로 옮기고 전체 또는 일부를 수행하십시오 (이로 인해 상황이 많이 느려지는데 놀랍습니다).
  • 무효 검사를 where 클래스의 맨 왼쪽으로 이동하고 모든 절을 사용하여 검사를 수행합니다 (이 작업도 느려지는데 전혀 놀라지 않습니다. 무효 검사는 항상 발생합니다. 여부 PA.mid = PB.mid).

내 목표는 내 쿼리를 두 번 복사하지 않고이 검사를 훨씬 빠르게 수행하는 것입니다.

이것이 가능합니까? 그렇지 않다면 왜 안 되겠습니까? 그렇다면 어떻게?

참고 : 제 2의 관련 질문 here도 참조하십시오.

+0

@Alex : 롤백. 아무도 sqlserver2005 태그를 사용하지 않으므로 다소 인기있는 sqlserver2005 태그 외에도이를 사용하는 것이 바보처럼 보입니다. SQL 태그는 중복되지만 덜 어리 석다. – Brian

+0

무언가가 장면 뒤에서 발생합니다. 어제는 sqlserver2005 태그가 인기가 있었지만 이제는 모든 내용이 sql-server-2005로 태그가 다시 지정되었습니다. –

+0

시도해 보셨습니까 (PB.inpo = @inpo 또는 @inpo가 null입니까?) –

답변

1

성능 저하없이 코드를 재사용하려면보기를 만들거나 인라인 UDF를 만들면됩니다. 둘 다 옵티 마이저에 의해 확장되는 매크로입니다. 대신 다음 코드 중복의 예를 들면 다음과 같습니다

CREATE PROCEDURE MyProc 
    @i1 INT, 
    @inpo INT 
AS 
BEGIN 
IF @inpo IS NULL BEGIN 
    SELECT a,b,c 
    FROM dbo.YourTable 
    WHERE i1 = @i1 
    ORDER BY c; 
END ELSE BEGIN 
    SELECT a,b,c 
    FROM dbo.YourTable 
    WHERE i1 = @i1 
     AND inpo = @inpo 
    ORDER BY c; 
END 
END 

그것을 인라인 UDF에서 쿼리를 포장 및 재사용 :

CREATE FUNCTION dbo.ReuseMyQuery(@i1 INT) 
RETURNS TABLE AS RETURN(
SELECT a,b,c, inpo FROM dbo.YourTable WHERE i1 = @i1 
) 
GO 

ALTER PROCEDURE MyProc 
    @i1 INT, 
    @inpo INT 
AS 
BEGIN 
IF @inpo IS NULL BEGIN 
    SELECT a,b,c 
    FROM dbo.ReuseMyQuery(@i1) 
    ORDER BY c; 
END ELSE BEGIN 
    SELECT a,b,c 
    FROM dbo.ReuseMyQuery(@i1) 
    WHERE inpo = @inpo 
    ORDER BY c; 
END 
END 
+0

필자의 견해 나 UDF에 포함 된 내용이 도움이 될지 확실하지 않습니다. – Brian

+0

내 직관은 with 문을 사용하고 뷰와 함수를 피할 수 있어야한다고 말하고 있지만 작동시키지 못했습니다. 임시 테이블을 대신 사용할 수도 있습니다. 내일 보겠습니다 :/ – Brian

+0

이 솔루션이 효과가 있습니다. – Brian

0

당신이이 일을 시도하면 어떻게 :

exists (select * from PRPB PB where PA.mid = PB.mid and PB.inpo = ISNULL(@inpo, PB.inpo)) order by price 

ISNULL 함수는 @inpo가 NULL 일 때 두 번째 매개 변수를 반환하고 PB.inpo를 반환하면 해당 등호는 항상 true로 평가되어 사용자 또는 조건과 일치합니다.

+0

내가 아는 한이 접근법은 색인에 적합하지 않습니다. 천천히 실행될 수 있습니다. –

+0

이것은 매우 느립니다. – Brian

관련 문제