Різниця продуктивності для COALESCE проти ISNULL?


48

Я бачив, як багато людей використовують функцію COALESCE замість ISNULL. Під час пошуку в Інтернеті я виявив, що COALESCE є стандартом ANSI, тому є перевага, що ми знаємо, чого очікувати при його використанні. Однак ISNULL здається простішим для читання, оскільки здається більш зрозумілим, що він робить.

Я також усвідомлюю, що ISNULL є дещо складним, оскільки діє по-різному на різних серверах баз даних та на різних мовах.

Все це, на мій погляд, зводиться до стилю та стандартів. Враховуючи, що стиль є суб'єктивним, чи є причина використовувати COALESCE над ISNULL (або навпаки)? Зокрема, чи є перевага ефективності одного над іншим?


1
Я не бачу в жодному з відповідей, що суб-запит у програмі COALESCE оцінюється двічі.
Мартін Сміт

4
"ISNULL здається простішим для читання, оскільки здається більш зрозумілим, що він робить" - справді? Я вважаю, що ім'я є неінтуїтивним: я б очікував, що він поверне булеве значення із зазначенням того, чи є вираз вирішеним на нульове чи невідоме. Назва COALESCEпросто неінтуїтивна;)
день, коли

Відповіді:


26

COALESCEвнутрішньо перекладається на CASEвираз, ISNULLє функцією внутрішнього двигуна.

COALESCEє стандартною функцією ANSI, ISNULLє T-SQL.

Різниці в продуктивності можуть і виникати, коли вибір впливає на план виконання, але різниця в швидкості функціонування є незначною .


40
  • ISNULL - це Sybase / SQL Server
  • COALESCE портативний

Тоді

  • ISNULL приймати 2 аргументи
  • COALESCE приймає 1-n аргументів

Нарешті, і веселощі. Результат даних та довжина / точність / масштаб

Цей останній біт, чому зазвичай використовується ISNULL, оскільки це більш передбачувано (?), А COALESCE може додавати ненавмисні перетворення типів даних: звідки походить біт "це повільніше"

DECLARE @len10 varchar(10); --leave it NULL
SELECT
    ISNULL(@len10, '0123456789ABCDEF'),     -- gives 0123456789
    COALESCE(@len10, '0123456789ABCDEF');   -- gives 0123456789ABCDEF

Усі типи даних однакові, практичної різниці ви не побачите ...


22

Як зауважив Марк, вам потрібно буде важко знайти відмінності в продуктивності; Я думаю, інші фактори будуть важливішими. Для мене я завжди використовую COALESCE, і більшість з цього ви вже згадували ви або Марк:

  • COALESCE - стандарт ANSI. Це одна річ, про яку я повинен переживати, якщо я збираюся перенести свій код. Для мене особисто це не так важливо, тому що я знаю, як рідко такі порти насправді трапляються за межами світу аудиторії Челко, але для деяких людей це користь.
  • На противагу тому, що ви сказали про читабельність, я вважаю, що це важче читати ISNULL, особливо для користувачів, які приходять з інших мов або платформ, де ISNULL повертає булева (яка не існує в SQL Server). Зрозуміло, що COALESCE важче написати, але, принаймні, це не призводить до неправильних припущень.
  • COALESCE набагато гнучкіший, як я можу сказати, COALESCE (a, b, c, d), тоді як з ISNULL я повинен був би зробити багато вкладених, щоб досягти того ж самого.

Ви також повинні бути впевнені, що знаєте, як керується пріоритетом типу даних за допомогою двох функцій, якщо ви використовуєте їх з різними типами / точними даними тощо.

Примітка

Є один виняток. У поточних версіях SQL Server вони обробляються по-різному:

SELECT COALESCE((SELECT some_aggregate_query),0); 

SELECT ISNULL((SELECT some_aggregate_query),0); 

COALESCEВаріант буде на самому ділі виконати some_aggregate_queryдвічі (один раз для перевірки значення, і один раз , щоб повернутися, коли ненульовий), а ISNULLтільки виконати підзапит один раз. Я говорю про кілька інших відмінностей тут:

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.