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.