Подтвердить что ты не робот

Что быстрее УГОЛ ИЛИ ИСКЛЮЧИТЕЛЬНО?

Я понимаю разницу между этими функциями, но мой вопрос заключается в том, что при проверке единственного нулевого значения ISNULL будет быстрее, чем использование COALESCE?

например

COALESCE(SELECT TOP 1 SomeValue FROM SomeTable, 0)

против

ISNULL(SELECT TOP 1 SomeValue FROM SomeTable, 0)
4b9b3361

Ответ 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 секунды.