Использование ISNULL против использования COALESCE для проверки конкретного условия?
Я знаю, что несколько параметров могут быть переданы в COALESCE
, но когда вы хотите к
проверьте только одно выражение, чтобы увидеть, если он не существует, вы используете по умолчанию или это лучше использовать ISNULL
вместо?
есть ли прирост производительности между этими двумя?
9 ответов:
эта проблема сообщается на 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
, так как последний не дублирует подзапрос.
Я думаю, что нет, но COALESCE находится в стандарте SQL '92 и поддерживается более различными базами данных. Если вы идете на переносимость, не используйте ISNULL.
стоит отметить, что тип обработки между ними также может иметь значение (см. это связанный с ответом пункт (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) на сам вопрос.
одна важная вещь, которую я не вижу явно указано, что
ISNULL
'S тип вывода аналогичен первому выражению, но с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'
где есть только одно условие null,
ISNULL
будет меньше накладных расходов. Однако разница, вероятно, незначительна.
это объяснение дает четкое представление о coalesce vs isnull
функция COALESCE в SQL возвращает первое ненулевое выражение среди своих аргументов. Синтаксис для объединения выглядит следующим образом:
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 () используется для замены нулевого значения другим значением.
select CountryName = ISNULL("columnname", 'INDIA') from Countries
Coalesce возвращает первое ненулевое выражение, где as isnull () используется для замените нулевое значение на наше желаемое значение.
COALESCE является частью стандартов ANSI и доступны практически во всех базах данных.
при принятии решения между ISNULL v COALESCE там параметры должны быть приняты во внимание:
- COALESCE определяет тип выходных данных на основе приоритета типа данных, где, как и в случае с ISNULL, тип данных не зависит от приоритета типа данных.
рассмотрим следующие 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 vs ISNULL проверьте это: https://www.mssqltips.com/sqlservertip/2689/deciding-between-coalesce-and-isnull-in-sql-server/
The
NULL
иCOALESCE
не всегда взаимозаменяемы. Он заслуживает того, чтобы знать их различия, чтобы знать, когда его лучше использовать один над другим:таблица выше сравнение между
ISNULL
иCOALESCE
СExam Ref 70-761 Querying Data with Transact-SQL
книга написана Ицик Бен-Ган.
- количество поддерживаемых параметров -
2
наISNULL
vs>2
при использованииCOALESCE
ISNULL
является проприетарной функцией T-SQL иCOALESCE
является стандартом ISO / ANSI SQLважен тип данных результата. После прочтения заметок в таблице выше, проверьте следующие случаи:
DECLARE @x VARCHAR(3) = NULL ,@y VARCHAR(10) = '1234567890'; SELECT ISNULL(@x, @y) AS [ISNULL], COALESCE(@x, @y) AS [COALESCE];
The
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];
The
ISNULL
возвращает тип данных первого аргумента, в то время как вCOALESCE
мы получаем ошибку, так какINT
имеет самый высокий приоритет и преобразование первого значения аргумента вINT
не удается.обнуление результата также может быть важным. Например:
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
свойства каждого столбца:используя
COALESCE
у нас естьNOT NULL
свойство столбца значениеYes
, только когда все входы не являются нулевыми.согласно стандарту SQL,
COALESCE
выражение преобразуется в:CASE WHEN (<subquery>) IS NOT NULL THEN (<subquery>) ELSE 0 END
если результат выполнения подзапроса в предложении WHEN не является NULL, SQL Server выполняет его во второй раз в предложении THEN. Другими словами, в таком случае он выполняет ее дважды. Только если результат выполнения в предложении WHEN равен NULL, SQL Server-Нет выполните подзапрос снова, а не возвращает выражение ELSE. Так при использовании подзапросов функция ISNULL имеет производительность преимущество.
в 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 он вернет второй параметр, и, конечно, вы можете проверить только для одного выражения...
Так что если хотите проверить несколько выражений и выбрать сначала не null среди них, то используйте coalesce в противном случае перейти на ISNULL