Есть ли в SQL Server разница между not (columnName = 'value') и columnName <> 'value'? - PullRequest
3 голосов
/ 11 января 2012

В предложении SQL Server where имеет значение, кодируете ли вы not(columnName='value') или columnName<>'value'?

Я думаю о производительности.

Мне сказали, что при использовании Not () он может не использовать индекс, который он в противном случае мог бы использовать с <>.

Ответы [ 3 ]

4 голосов
/ 11 января 2012

Лучше всего проверить планы выполнения. Когда я тестирую следующее в SQL Server 2008, они дают идентичные планы (и оба переводятся в 2 поиска диапазона). Поэтому <> x преобразуется в > x ИЛИ < x)

CREATE TABLE T
  (
     C INT,
     D INT,
     PRIMARY KEY(C, D)
  )

INSERT INTO T
SELECT 1,
       1
UNION ALL
SELECT DISTINCT 2,
                number
FROM   master..spt_values

SELECT *
FROM   T
WHERE  NOT ( C = 2 )

SELECT *
FROM   T
WHERE  ( C <> 2 )  

Придает

  |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1010], [Expr1011], [Expr1012]))
       |--Merge Interval
       |    |--Sort(TOP 2, ORDER BY:([Expr1013] DESC, [Expr1014] ASC, [Expr1010] ASC, [Expr1015] DESC))
       |         |--Compute Scalar(DEFINE:([Expr1013]=((4)&[Expr1012]) = (4) AND NULL = [Expr1010], [Expr1014]=(4)&[Expr1012], [Expr1015]=(16)&[Expr1012]))
       |              |--Concatenation
       |                   |--Compute Scalar(DEFINE:([Expr1005]=NULL, [Expr1006]=CONVERT_IMPLICIT(int,[@1],0), [Expr1004]=(10)))
       |                   |    |--Constant Scan
       |                   |--Compute Scalar(DEFINE:([Expr1008]=CONVERT_IMPLICIT(int,[@1],0), [Expr1009]=NULL, [Expr1007]=(6)))
       |                        |--Constant Scan
       |--Clustered Index Seek(OBJECT:([test].[dbo].[T].[PK__T__B86D18326339AFF7]), SEEK:([test].[dbo].[T].[C] > [Expr1010] AND [test].[dbo].[T].[C] < [Expr1011]) ORDERED FORWARD)

Plan

3 голосов
/ 11 января 2012

Оптимизатор иногда может удивить своим умением переводить выражения во что-то другое, но более быстрое.

Скажем, если вы выбираете из таблицы несколько уникальных значений, и у SQL Server есть средства, чтобы вычислять тамна самом деле мало уникальных значений (скажем, 1, 2 и 3), тогда where x<>2 может даже в конечном итоге преобразоваться в некое подобие [Union1004] = (1) OR [Union1004] = (3), которое несколько не связано с исходным выражением, но дасттребуемый результат.

То есть, не беспокойтесь об этом уровне производительности.SQL Server все равно будет его портить.

1 голос
/ 11 января 2012

Если оба аргумента имеют значение NON-NULL - они эквивалентны

НО

Даже если любой из них имеет нулевое значение - они все равно эквивалентны, но вы не можете полагаться на них 8 -)

Упомянутое выше в цитировании: НЕ ПРАВДА , спасибо за @Martin Smith

Единственное, что имеет значение и отличается по производительности - если вы используете отфильтрованные индексы, чем оптимизатор ищет отфильтрованный индекс, а не нормализует условие, но простая лексическая эквивалентность.

Итак, если у вас есть индекс по columnName, отфильтрованный с помощью оператора WHERE columnName<>'value', то в случае, если вы напишите columnName<>'value' в ГДЕ выбора - индекс может использоваться, в зависимости от других условия, если вы пишете not(columnName='value') - индекс даже не будет считаться

И

Не пытайтесь помочь оптимизатору выполнять свою работу. Это очень сложно, так что - не путайте это 8-) Или сделайте это, если вы действительно знаете , что именно вы делаете и как это влияет на поведение оптимизатора

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...