SQL Server에서 <>와! =의 성능이 동일한 신뢰할 수있는 소스


74

SO에 대한이 답변 을 고려 하여 <>운영자에게 다음과 같은 질문 을 하십시오 .

<>입니다 ... 같은 !=.

그러나 주석 작성자는 파이프를 통해 다음과 같이 말합니다.

그것들이 기능적으로 동일하다는 것은 사실입니다. 그러나 SQL 옵티마이 저가이를 사용하는 방법은 매우 다릅니다. = /! =는 단순히 true / false로 평가되는 반면 <>은 엔진이 값이 크거나 작은 지 확인하여 성능 오버 헤드가 더 크다는 것을 의미합니다. 비싼 쿼리를 작성할 때 고려해야 할 사항.

나는 이것이 틀렸다고 확신하지만, 잠재적 회의론자들을 해결하기 위해,이 운영자들이 기능적으로 동일 할뿐 아니라 모든 측면에서 동일하다는 것을 증명할 수있는 정식 또는 정식 출처를 제공 할 수 있는지 궁금합니다.

답변:


144

구문 분석 중 SQL Server는 다음 sqllang!DecodeCompOp과 같은 비교 연산자 유형을 결정하기 위해 호출 합니다.

콜 스택

이것은 옵티마이 저의 어떤 것이 관여되기 전에 발생합니다.

에서 비교 연산자 (Transact-SQL)를 참조하십시오

비교 연산자와 의미

디버거 및 공용 기호 *를 사용하여 코드를 추적하면 다음과 같이 sqllang!DecodeCompOp레지스터 eax**에 값이 반환 됩니다.

╔════╦══════╗
║ Op ║ Code ║
╠════╬══════╣
║ <  ║    1 ║
║ =  ║    2 ║
║ <= ║    3 ║
║ !> ║    3 ║
║ >  ║    4 ║
║ <> ║    5 ║
║ != ║    5 ║
║ >= ║    6 ║
║ !< ║    6 ║
╚════╩══════╝

!=그리고 <>둘 다 너무이며, 5를 반환 구별 (컴파일 및 최적화 포함) 이후의 모든 작업을한다.


위의 지점에 차 있지만, 그것은 또한 가능하다 (예를 들어, 문서화되지 않은 추적 플래그 8605 사용) 그 모두를 확인하기 위해 최적화에 전달 논리적 트리를 보는을 !=하고 <>매핑 ScaOp_Comp x_cmpNe(동일하지 스칼라 연산자 비교).

예를 들면 다음과 같습니다.

SELECT P.ProductID FROM Production.Product AS P
WHERE P.ProductID != 4
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8605);

SELECT P.ProductID FROM Production.Product AS P
WHERE P.ProductID <> 4
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8605);

둘 다 생산 :

LogOp_Project QCOL : [P] .ProductID
    LogOp_Select
        LogOp_Get TBL : Production.Product (별칭 : TBL : P)
        ScaOp_Comp x_cmpNe
            ScaOp_Identifier QCOL : [P] .ProductID
            ScaOp_Const TI (int, ML = 4) XVAR (int, Not Owned, Value = 4)
    AncOp_PrjList 

각주

* WinDbg를 사용합니다 . 다른 디버거도 사용할 수 있습니다. 공용 심볼은 일반적인 Microsoft 심볼 서버를 통해 사용할 수 있습니다. 자세한 내용 은 SQL Server 고객 자문 팀의 미니 덤프 및 Klaus Aschenbrenner 의 소개 인 WinDbg를 사용한 SQL Server 디버깅을 통한 SQL Server 심층 분석을 참조하십시오 .

** 함수의 반환 값으로 32 비트 Intel 파생 제품에서 EAX를 사용하는 것이 일반적입니다. 확실히 Win32 ABI는 그런 식으로 작동하며 AX가 같은 목적으로 사용되었던 옛날 MS-DOS 시절부터 그 관행을 상속 받았다고 확신합니다-Michael Kjörling


58

Microsoft에서 SQL 지원을 담당하고 있으며 SQL Server 성능의 수석 에스컬레이션 엔지니어이자 주제 전문가 인 Jack Li에게 "SQL이!>와 다르게 처리됩니까?" 그는 "그들은 동일합니다."


8

다음은 <>2 가지 비교 를 하지 않는 것으로 입증 됩니다.

  1. SQL 표준 92는 <>같지 않은 연산자로 정의합니다 ( http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt ). 기술적으로 !=는 표준을 확장 한 것입니다 (표준을 구현하지 않는 RDBMS는 생각할 수 없지만).
  2. SQLServer가 <>하나가 아닌 2 개의 연산자로 처리되면 ><실제로 구문 오류 인 것과 동일한 작업을 수행합니다 .

1

온라인 설명서 (BOL)는 기능상 동일하다고 말합니다.

! = (같지 않음) (Transact-SQL)

그리고 !=Predicate에서 사용 된 실행 계획을 보면로 변경 != 됩니다 <>.


2
문제는 "기능적으로 동일한"언어가 참조 된 주석에서 이미 인정되었지만, "기능적으로 동일하다"는 실제 작동 방식 및 그 성능 특성을 포함한다는 당신과 나의 지식에도 불구하고 성능에 대해 추가적인 구별을한다는 것입니다. 결정된 모든 회의론을 넘어서 이것을 증명하려고한다면 어떻게해야할까요?
— ErikE
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.