Авторитетный источник, который <> и! = идентичны по производительности в SQL Server

Рассмотрим этот ответ на SO, который заверяет об этом в вопросе оператора <> что:

  

<> является ... таким же, как !=.

Но затем комментатор завершает трубку и говорит:

  

Это правда, что они функционально одинаковы. Однако, как оптимизатор SQL использует их, очень отличается. = /! = просто вычисляются как истинные /ложные, тогда как <> означает, что движок должен смотреть и видеть, превышает ли значение значение или меньше, что означает большую нагрузку на производительность. Просто что-то учитывать при написании запросов, которые могут быть дорогими.

Я уверен, что это ложь, но для того, чтобы обратиться к потенциальным скептикам, мне интересно, может ли кто-нибудь предоставить авторитетный или канонический источник, чтобы доказать, что эти операторы не только функционально одинаковы, но идентичны во всех аспектах?

66 голосов | спросил ErikE 18 52016vEurope/Moscow11bEurope/MoscowFri, 18 Nov 2016 01:39:48 +0300 2016, 01:39:48

4 ответа


132

В процессе синтаксического анализа 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 с помощью Minidumps с помощью Консультативной группы клиентов SQL Server и Отладка SQL Server с помощью WinDbg - введение Клауса Ашенбреннера.

** Использование EAX на 32-разрядных процессорах Intel для возвращаемых значений из функции является общим. Конечно, Win32 ABI делает это именно так, и я уверен, что он наследует эту практику со старых времен MS-DOS, где AX использовался для этой же цели - Michael Kj¶rling Суб>

ответил Paul White 18 52016vEurope/Moscow11bEurope/MoscowFri, 18 Nov 2016 08:44:02 +0300 2016, 08:44:02
57

Я работаю в Microsoft в поддержке SQL, и я спросил Джека Ли, старшего инженера по эскалации и эксперта по экспертным вопросам производительности SQL Server: «Does SQL обрабатывает! = любой по-другому, чем <>?» и он сказал: «Они те же».

ответил stacylaray 18 52016vEurope/Moscow11bEurope/MoscowFri, 18 Nov 2016 06:22:33 +0300 2016, 06:22:33
8

Я думаю, что следующее доказывает, что <> не выполняет 2 сравнения.

  1. SQL Standard 92 определяет <> как не равный оператор, ( http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt ). Технически, != является расширением стандарта (хотя я не могу думать о каких-либо РСУБД, которые его не реализуют).
  2. Если SQLServer обрабатывал <> как 2 оператора, а не один, он будет делать то же самое для ><, который является фактически синтаксической ошибкой.
ответил a1ex07 18 52016vEurope/Moscow11bEurope/MoscowFri, 18 Nov 2016 03:29:54 +0300 2016, 03:29:54
1

Это неверно, Books Online (BOL) говорит, что они функционально одинаковы:

! = (не равно) (Transact-SQL)

И если вы посмотрите план выполнения, в котором используется !=, в разделе Predicate он изменяет != на <>

ответил Ryan Cooper 30 32016vEurope/Moscow11bEurope/MoscowWed, 30 Nov 2016 20:49:42 +0300 2016, 20:49:42

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132