isnull vs is null - PullRequest
       10

isnull vs is null

19 голосов
/ 25 июня 2010

Я заметил, что несколько запросов на работе и в SO используют ограничения в форме:

isnull(name,'') <> ''

Есть ли конкретная причина, почему люди делают это, а не более кратко

name is not null

Это наследие или проблема с производительностью?

Ответы [ 10 ]

35 голосов
/ 25 июня 2010
where isnull(name,'') <> ''

эквивалентно

where name is not null and name <> '' 

что в свою очередь эквивалентно

where name <> ''

(если имя IS NULL, то последнее выражение будет иметь значение неизвестно, а строка не будет возвращена)

Использование шаблона ISNULL приведет к сканированию и будет менее эффективным, как видно из следующего теста.

SELECT ca.[name],
       [number],
       [type],
       [low],
       [high],
       [status]
INTO   TestTable
FROM   [master].[dbo].[spt_values]
       CROSS APPLY (SELECT [name]
                    UNION ALL
                    SELECT ''
                    UNION ALL
                    SELECT NULL) ca 


CREATE NONCLUSTERED INDEX IX_TestTable ON dbo.TestTable(name)

GO


SELECT name FROM TestTable WHERE isnull(name,'') <> ''

SELECT name FROM TestTable WHERE name is not null and name <> ''
/*Can be simplified to just WHERE name <> '' */

Что должно дать вам план выполнения, который вам нужен.

enter image description here

13 голосов
/ 25 июня 2010
is not null

Будет только проверять, если поле не является нулевым. Если поле содержит пустую строку, то это поле больше не равно нулю.

isnull(name, '') <> name

Проверяет как пустую, так и пустую строку.

2 голосов
/ 25 июня 2010

isnull(name,'') <> :name является сокращением для (name is null or name <> :name) (при условии, что :name никогда не содержит пустую строку, поэтому такие сокращения могут быть плохими). ​​

Производительность зависит от ситуации. Операторы or в предложениях where могут дать очень плохую производительность. Однако функции в столбцах ухудшают использование индекса. Как обычно: профиль.

1 голос
/ 25 июня 2010

Другие указали на функциональную разницу.Что касается проблемы производительности, в Postgres я обнаружил, что - о, я должен упомянуть, что в Postgres есть функция «coalesce», которая эквивалентна «isnull», встречающемуся в некоторых других диалектах SQL - но в Postgres, говоря

where coalesce(foobar,'')=''

значительно быстрее, чем

where foobar is null or foobar=''

Кроме того, это может быть удивительно быстро сказать

 where foobar>''

над

where foobar!=''

Тест больше, чем может использовать индекс и, таким образом, пропустить все пробелы, в то время как неравный тест должен выполнить полное чтение файла.(Предполагается, что у вас есть индекс для поля, и в индексе не используется никакой другой индекс.)

1 голос
/ 25 июня 2010

Я явно неправильно понял ваш вопрос.Итак, позвольте мне дать свой первый ответ и попробовать этот:

isnull(name,'') <> ''

- ошибочное сочетание для

name is not null and name <> ''
1 голос
/ 25 июня 2010

Они не имеют в виду одно и то же.

name is not null 

Проверяет записи, в которых поле имени равно нулю

isnull(name,'') <> name  

Этот параметр изменяет значение пустых полей на пустую строку, чтобы их можно было использовать при сравнении. В SQL Server (но не в Oracle, я думаю), если значение равно нулю и оно используется для сравнения равенства или неравенства, оно не будет считаться, потому что значение равно нулю, значит, я не знаю значение и, следовательно, не является фактическим значением. Поэтому, если вы хотите убедиться, что нулевые записи учитываются при выполнении сравнения, вам нужно ISNULL или COALESCE (это термин ASCII STANDARD, который нужно использовать, поскольку ISNULL не работает во всех базах данных).

То, на что вы должны смотреть, - это различие между

isnull(a.name,'') <> b.name  

a.name <> b.name

тогда вы поймете, почему ISNULL необходим для получения правильных результатов.

1 голос
/ 25 июня 2010
isnull(name,'') <> name

Ну, я вижу, как они используют это, потому что, если имя не совпадает или равно нулю, оно возвращается как неудачное сравнение.Это действительно означает: name is null или name <> name

Где этот name is not null просто проверяет, является ли имя пустым.

0 голосов
/ 25 июня 2010

Обрабатывает как пустую строку, так и NULL.Хотя хорошо иметь дело с одним оператором, isnull является проприетарным синтаксисом.Я бы написал это, используя переносимый стандарт SQL как

NULLIF(name, '') IS NOT NULL
0 голосов
/ 25 июня 2010

Эти два запроса не совпадают. Например, у меня нет отчества, это известный факт, который можно сохранить как

MiddleName=''

Однако, если мы не знаем чье-то второе имя, мы можем хранить NULL. Итак, ISNULL (MiddleName, '') означает "лица без известных отчеств".

0 голосов
/ 25 июня 2010

Также, если вы хотите использовать индекс для этого столбца, используйте

name is not null and name <> '' 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...