Что быстрее УГОЛ ИЛИ ИСКЛЮЧИТЕЛЬНО?
Я понимаю разницу между этими функциями, но мой вопрос заключается в том, что при проверке единственного нулевого значения ISNULL будет быстрее, чем использование COALESCE?
например
COALESCE(SELECT TOP 1 SomeValue FROM SomeTable, 0)
против
ISNULL(SELECT TOP 1 SomeValue FROM SomeTable, 0)
Ответы
Ответ 1
Был бы быстрый взгляд на это, поскольку мне интересно увидеть ряд разных сравнений там, где производительность между 2. Я думаю, this сообщение блога Адама Мачанича наиболее точным в тесте производительности, выполненном по этой теме, где нижняя строка:
... и ISNULL выглядит довольно последовательно удалять COALESCE в среднем 10 или 12 процентов
Однако, я разделяю ту же точку зрения, что и то, что он затем говорит, - что разница довольно незначительна - например, в его испытаниях, миллионы экзекуций показали в среднем разницу 0,7. Стоит ли оно того? Я бы предположил, что есть, вероятно, большие области для оптимизации. Но прочитайте статью, это хорошо прочитано.
Ответ 2
В этом случае ISNULL - лучший вариант. Поскольку SQL Server интерпретирует функцию COALESCE как оператор CASE. Итак, ваш запрос
COALESCE (SELECT TOP 1 SomeValue FROM SomeTable, 0)
будет записываться SQL Server как
- CASE
- КОГДА (ВЫБРАТЬ TOP 1 SomeValue FROM SomeTable) НЕ НУЛЛ
- THEN (ВЫБОР TOP 1 SomeValue FROM SomeTable)
- ELSE 0
- END
Если вы соблюдаете приведенную выше интерпретацию, "SomeTable" будет проверяться дважды. Но ISNULL будет оцениваться только один раз.
Ответ 3
ISNULL
будет быстрее, я думаю, потому что он имеет меньшую реализацию функции/кода для себя, делая его быстрее, чем COALESCE
Ответ 4
Пожалуйста, проверьте ссылку
для предпочтения ISNULL
над COALESCE
, когда задано, выбор состоит в том, что ISNULL
имеет тенденцию создавать планы запросов, которые более эффективны, чем COALESCE
.
Ответ 5
В чем его ценность У вас есть очень конкретный прецедент, поэтому я использовал образец вашего фактического вопроса о первом значении таблицы, который пришел на ум и контролировал script для других переменных. Я предположил, что someval был int, когда вы использовали 0. Мое предложение состоит в том, что вы выбираете свой конкретный someval/sometable case и сами выполняете тест.
declare @val int = 0;
declare @time1 Datetime2 = getdate();
declare @time2 Datetime2 = getdate();
Select @time1 = GETDATE();
while @MyCounter < 1000000
Begin
Select @val = ISNULL((SELECT TOP 1 LocationID FROM location), 0)
Select @MyCounter +=1;
END
Select @time2 = GETDATE();
Print datediff(millisecond,@time1,@time2);
Select @MyCounter = 0;
Select @time1 = GETDATE();
while @MyCounter < 1000000
Begin
Select @val = COALESCE((SELECT TOP 1 LocationID FROM Location), 0)
Select @MyCounter +=1;
END
Select @time2 = GETDATE();
Print datediff(millisecond,@time1,@time2);
Результаты были довольно драматичными, 11270 для isnull и 18930 для coalesce. Реверсирование порядка циклов в качестве второго теста производило 18260 для coalesce и 10810 для isnull. Для вашего конкретного случая я бы сказал, что isnull явно быстрее.
Это не значит, что лучше в любой другой ситуации. Использование прямых значений или nvarchars или бит вместо int или столбца, который не является первичным ключом, или Nesting isnull в сравнении с добавлением параметров для объединения может изменить ситуацию.
Это касается только того вопроса, который был задан.
Ответ 6
Я просто проверил тест на своем собственном дБ. Около 700 тыс. Строк.
SELECT COUNT(*) FROM table WHERE COALESCE(field_1,field_2,field_3,field_4) IS NOT NULL
Результат 12106
, полученный за 56 секунд.
SELECT COUNT(*) FROM table WHERE field_1 IS NOT NULL OR field_2 IS NOT NULL OR field_3 IS NOT NULL OR field_4 IS NOT NULL
Результат 12106
, полученный за 0,00 секунды.