Использование ISNULL против использования COALESCE для проверки определенного условия? - PullRequest
69 голосов
/ 14 сентября 2011

Я знаю, что множественные параметры могут быть переданы COALESCE, но когда вы хотите отметьте только одно выражение, чтобы увидеть, не существует ли оно, вы используете значение по умолчанию или лучше вместо него использовать ISNULL?

Есть ли прирост производительности между этими двумя?

Ответы [ 9 ]

55 голосов
/ 29 февраля 2012

Эта проблема, о которой сообщалось в Microsoft Connect , выявляет некоторые различия между COALESCE и ISNULL:

ранняя часть нашей обработки переписывает COALESCE( expression1, expression2 ) как CASE WHEN expression1 IS NOT NULL THEN expression1 ELSE expression2 END. В [этом примере]:

COALESCE ( ( SELECT Nullable
             FROM Demo
             WHERE SomeCol = 1 ), 1 )

мы генерируем:

SELECT CASE
          WHEN (SELECT Nullable FROM Demo WHERE SomeCol = 1) IS NOT NULL
          THEN (SELECT Nullable FROM Demo WHERE SomeCol = 1)
          ELSE 1
       END

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

Один из обходных путей, хотя мне неприятно это предлагать, - это изменить COALESCE на ISNULL, поскольку последний не дублирует подзапрос.

24 голосов
/ 14 сентября 2011

Я думаю, что нет, но COALESCE соответствует стандарту SQL '92 и поддерживается более различными базами данных.Если вы предпочитаете переносимость, не используйте ISNULL.

11 голосов
/ 13 марта 2014

В COALESCE вы можете иметь несколько выражений, где, как и в ISNULL , вы можете проверить только одно выражение

COALESCE ( expression [ ,...n ] ) 

ISNULL ( check_expression , replacement_value )
6 голосов
/ 07 октября 2014

Стоит отметить, что обработка типов между ними также может иметь значение (см. этот связанный элемент ответа (2) ).

Допустим, запрос пытается использовать ярлык для записи нулевого сравнения:

select * from SomeTable
 where IsNull(SomeNullableBitField, -1) != IsNull(SomeOtherNullableBitField, -1);

что отличается от

select * from SomeTable
 where coalesce(SomeNullableBitField, -1) != coalesce(SomeOtherNullableBitField, -1);

Потому что в первом случае IsNull () заставляет тип быть битовым (поэтому -1 преобразуется в true), тогда как во втором случае оба преобразуются в int.

with input as 
(
  select convert(bit, 1) as BitOn,      
         convert(bit, 0) as BitOff,
         convert(bit, null) as BitNull
)
select BitOn, 
       BitOff,
       BitNull,
       IsNull(BitOn, -1) IsNullBitOn,         -- true
       IsNull(BitOff, -1) IsNullBitOff,       -- false
       IsNull(BitNull, -1) IsNullBitNull,     -- true, converts the -1 to bit
       coalesce(BitOn, -1) CoalesceBitOn,     -- 1
       coalesce(BitOff, -1) CoalesceBitOff,   -- 0       
       coalesce(BitNull, -1) CoalesceBitNull  -- -1
  from input;

Существует аналогичный комментарий / ссылка (@Martin Smith) на сам вопрос.

5 голосов
/ 10 июня 2015

Одна важная вещь, которую я не вижу в явном виде, это то, что тип вывода ISNULL похож на первое выражение, но с COALESCE он возвращает тип данных со значением наивысшего приоритета.

DECLARE @X VARCHAR(3) = NULL
DECLARE @Y VARCHAR(10) = '123456789'
/* The datatype returned is similar to X, or the first expression*/
SELECT ISNULL(@X, @Y) ---> Output is '123'
/* The datatype returned is similar to Y, or to the value of highest precedence*/
SELECT COALESCE(@X, @Y) ---> Output is '123456789'
2 голосов
/ 27 мая 2017

Это объяснение дает ясное представление о coalesce vs isnull

Функция COALESCE в SQL возвращает первое не-NULL выражение среди своих аргументов.Синтаксис COALESCE выглядит следующим образом:

 COALESCE ("expression 1", "expressions 2", ...)

Это то же самое, что и следующий оператор CASE:

SELECT CASE ("column_name")
  WHEN "expression 1 is not NULL" THEN "expression 1"
  WHEN "expression 2 is not NULL" THEN "expression 2"
  ...
  [ELSE "NULL"]
  END
FROM "table_name";

В SQL Server функция ISNULL () используется для замены NULL.значение с другим значением.

select CountryName = ISNULL("columnname", 'INDIA') from Countries

Coalesce возвращает первое ненулевое выражение, где asnull () используется для замены нулевого значения нашим желаемым значением.

COALESCE является частью стандартов ANSI идоступны почти во всех базах данных.

при выборе между ISNULL v COALESCE необходимо позаботиться о параметрах:

  1. COALESCE определяет тип вывода на основе приоритета типа данных, гдекак и в случае ISNULL, тип данных не зависит от приоритета типа данных.
  2. Рассмотрим следующие операторы sql

    DECLARE @c5 VARCHAR(5);
    SELECT 'COALESCE', COALESCE(@c5, 'longer name')
    UNION ALL
    SELECT 'ISNULL',   ISNULL(@c5,   'longer name');
    

Результаты:

COALESCE longer name
ISNULL   longe

Это происходит потому, что ISNULL принимает тип данных первого аргумента, а COALESCE проверяет все элементы и выбирает наиболее подходящее (в данном случае VARCHAR (11))

Дляболее подробное объяснение выбора между COALESCE и ISNULL проверьте это: https://www.mssqltips.com/sqlservertip/2689/deciding-between-coalesce-and-isnull-in-sql-server/

2 голосов
/ 14 сентября 2011

Там, где есть только одно нулевое условие, ISNULL будет иметь меньше накладных расходов.Разница, вероятно, ничтожна.

1 голос
/ 05 октября 2017

NULL и COALESCE не всегда взаимозаменяемы.Следует знать их различия, чтобы знать, когда лучше использовать одно над другим:

enter image description here

В таблице выше приведено сравнение между ISNULL и COALESCE из Exam Ref 70-761 Querying Data with Transact-SQL книги, написанной Ицик Бен-Ганом.


  1. Количество поддерживаемых параметров - 2 для ISNULL против >2 при использовании COALESCE
  2. ISNULL является проприетарной функцией T-SQL, а COALESCE является стандартом ISO / ANSI SQL
  3. Тип данных результата важен.После прочтения примечаний в приведенной выше таблице проверьте следующие случаи:

    DECLARE @x VARCHAR(3)  = NULL
           ,@y VARCHAR(10) = '1234567890';
    
    SELECT ISNULL(@x, @y) AS [ISNULL], COALESCE(@x, @y) AS [COALESCE];
    

    enter image description here

    ISNULL получает тип данных первого аргументакак это не NULL буквальный.Это VARCHAR(3) и является результатом, данные второго аргумента обрезаются, чтобы соответствовать ему.С COALESCE типом данных, если используется наивысший приоритет.

    DECLARE @x VARCHAR(8)  = '123x5'
           ,@y INT = 123;
    
    SELECT ISNULL(@x, @y) AS [ISNULL];
    SELECT COALESCE(@x, @y) AS [COALESCE];
    

    enter image description here

    enter image description here

    ISNULL возвращает тип данных первого аргумента, в то время как в COALESCE мы получаем ошибку, так как INT имеет наивысший приоритет и преобразование значения первого аргумента в INT не удается.

  4. Обнуляемость результата также может быть важна.Например:

    DECLARE @x VARCHAR(3) = NULL
           ,@y VARCHAR(3) = NULL;
    
    DROP TABLE IF EXISTS [dbo].[DataSource01];
    
    SELECT ISNULL(10, 20) AS [C1]
          ,ISNULL(@x, 'text') AS [C2]
          ,ISNULL(@x, @y) AS [C3]
    INTO [dbo].[DataSource01];
    
    DROP TABLE IF EXISTS [dbo].[DataSource02];
    
    SELECT COALESCE(10, 20) AS [C1]
          ,COALESCE(@x, 'text') AS [C2]
          ,COALESCE(@x, @y) AS [C3]
    INTO [dbo].[DataSource02];
    

    Давайте проверим свойство Nullable каждого столбца:

    enter image description here

    enter image description here

    Используя COALESCE, мы имеем свойство NOT NULL столбца, установленное на Yes, только если все входные данные не имеют нулевого значения.

  5. В соответствии со стандартом SQL выражение COALESCE переводится в:

    CASE WHEN (<subquery>) IS NOT NULL THEN (<subquery>) ELSE 0 END
    

    Если результат выполнения подзапроса в предложении WHEN не равен NULL, SQL Serverвыполняет его во второй раз в предложении THEN.Другими словами, в таком случае он выполняет его дважды.Только если результат выполнения в предложении WHEN равен NULL, SQL Server больше не выполняет подзапрос, а возвращает выражение ELSE.Поэтому при использовании подзапросов функция ISNULL имеет преимущество в производительности.

0 голосов
/ 16 апреля 2014

В COALESCE можно использовать несколько выражений, он вернет значение, которое не является нулевым и встречается первым ... например

DECLARE @Value1 INT, @Value2 INT, @Value3 INT, @Value4 INT
SELECT @Value2 = 2, @Value4 = 4
SELECT COALESCE(@Value1, @Value2, @Value3, @Value4)
SELECT COALESCE(@Value1, @Value4, @Value3, @Value2)

А в ISNULL, если выражение null, оно будет возвращать второй предоставленный параметр, и, конечно, вы можете проверить только одно выражение ...

Так что, если хотите проверить несколько выражений и выбрать сначала не нуль среди них, то используйте coalesce, в противном случае перейдите к ISNULL

...