문제

나는 쿼리 최적화를 위해 노력해 왔으며 항상 SQL 또는 운영자를 어떻게 사용했는지 의문을 갖는 상황에 부딪쳤다. (SQL Server 2000도)

조건부 조항이 다음과 같이 보이는 쿼리가 있습니다.

WHERE (Column1 = @Param1 or Column1 LIKE @Param1 + '%')
AND (@Param2 = '' OR Column2 = @Param2 OR Column2 LIKE @Param2 + '%')

이제는 항상 또는 SQL에서 두 표현을 평가했습니다. 따라서 왼쪽 표현식에 대해 True를 평가 한 모든 레코드는 오른쪽 표현식에서 True를 평가 한 모든 레코드와 함께 반환됩니다. 예를 들어:

SELECT * FROM TABLE1
WHERE COL1 = 'Test' OR Col2 = 'Data'

이것은 Col1이 가장 적합하지 않은 모든 레코드와 Col2가 '데이터'인 레코드를 되돌려줍니다.

위의 예에서, 나는 다음과 같은 column2를 조건부로 수정했다.

AND(Column2 LIKE ISNULL(@Param2, '') + '%')

갑자기, 나는 0 줄을 반환한다.

진정한 결과를 찾을 때까지 그 표현 만 잘못 평가했거나 표현 만 평가 했습니까?

도움이 되었습니까?

해결책

"또는 진정한 결과를 찾을 때까지 표현 만 평가합니다."

그럴 필요가 있지만 그것은 당신의 문제가 아닙니다 (실제로 이것은 원래의 경우에 당신을 구하는 것입니다). 두 쿼리는 실제로 동일하지 않습니다.

나는 당신이 가지고 있다고 생각합니다 NULLcourmal2에서 s는 결코 원인이되지 않습니다 (Column2 LIKE ISNULL(@Param2, '') + '%') 사실 - 그리고 당신의 원래 버전에서 @Param2 = '' 이 사건을 마스킹하고 있었는데, 그것은 사실이기 때문에 (때로는)

아마도:

(ISNULL(Column2, '') LIKE ISNULL(@Param2, '') + '%')

Nulls에 대한 3 값 논리를 기억하십시오.

TRUE and UNKNOWN: UNKNOWN
TRUE or UNKNOWN: TRUE

FALSE and UNKNOWN: FALSE
FALSE or UNKNOWN: UNKNOWN

그러나 나는 당신의 최적화가 실제로 도움이 될 것이라고 확신하지 못합니다.

다른 팁

또는 특히 괄호 안에있는 것처럼 포괄적이지 않습니다. 그 이후로 당신이 더 크게 가지고있는 것은 다음과 같습니다. WHERE X AND Y. X와 Y가 자체적으로 사용되거나 중요하지 않은 부울 표현이라는 사실 : 별도로 평가 한 다음 결과는 및 연산자에게 공급됩니다.

편집하다]:
다시 읽어 보면, 나는 당신의 질문을 오해했을 것입니다. 그 점을 염두에두고 다른 대답을 가지고 가야합니다. NULL LIKE '%' 이 경우 널을 반환합니다.이 경우 거짓과 동일합니다. 대신 시도해 볼 수 있습니다.

COALESCE(Column2,'') LIKE COALESCE(@param2,'') + '%'

참고로, 모든 조건이 반드시 평가되는 것은 아니라는 것을 알기 위해 할 수있는 매우 간단한 실험이 있습니다.

나는 이것을 Oracle에서했지만 SQL Server에서 비슷한 결과를 얻을 것으로 기대합니다.

dev> select * from dual where 1=1 or 1/0 = 3;

D
-
X

제로별로 오류가 발생하기 때문에 또는 평가 된 조건은 평가되지 않아야합니다.

부울 운영자 의이 취급은 일반적으로 "단락"으로 알려져 있으며 Afaik은 현대 언어에서 매우 표준입니다. 또한 첫 번째 조건이 거짓이라면 전체 표현식이 사실 일 수 없기 때문에 두 번째 조건을 평가할 필요가 없습니다.

더 많은 정보: http://en.wikipedia.org/wiki/short-circuit_evaluation

어쨌든 Cade가 말했듯이, 당신의 실제 문제는 아마도 Nulls의 잘못 처리 일 것입니다.

MS-SQL은 먼저 왼쪽을 평가하고 필요하지 않으면 진행하지 않습니다.

이것은 동일하고 커넥터와 동일합니다. 왼쪽이 평가되고 오른쪽이 오른쪽이 회복되지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top