it-swarm.dev

Różnica wydajności dla COALESCE kontra ISNULL?

Widziałem wiele osób korzystających z funkcji COALESCE zamiast ISNULL. Z wyszukiwarek internetowych dowiedziałem się, że COALESCE jest standardem ANSI, więc mamy tę zaletę, że wiemy, czego się spodziewać podczas jego używania. Jednak ISNULL wydaje się łatwiejszy do odczytania, ponieważ wydaje się bardziej jasne, co robi.

Zdaję sobie również sprawę, że ISNULL jest dość trudny, ponieważ działa inaczej na różnych serwerach baz danych i w różnych językach.

Wszystko to, moim zdaniem, sprowadza się do stylu i standardów. Biorąc pod uwagę, że styl jest subiektywny, czy jest jakiś powód, aby używać COALESCE zamiast ISNULL (lub odwrotnie)? W szczególności, czy istnieje przewaga wydajności jednego nad drugim?

51
Richard

COALESCE jest wewnętrznie przetłumaczone na wyrażenie CASE, ISNULL jest wewnętrzną funkcją silnika.

COALESCE jest standardową funkcją ANSI, ISNULL to T-SQL.

Różnice w wydajności mogą powstać, gdy wybór wpływa na plan wykonania, ale różnica w szybkości funkcji pierwotnej jest niewielka .

28
  • ISNULL jest specyficzny dla Sybase/SQL Server
  • COALESCE jest przenośny

Następnie

  • ISNULL przyjmuje 2 argumenty
  • COALESCE przyjmuje argumenty 1-n

Wreszcie i trochę zabawy. Wynikowy typ danych i długość/precyzja/skala

Ten ostatni bit jest powodem, dla którego ISNULL jest zwykle używany, ponieważ jest bardziej przewidywalny (?), A COALESCE może dodawać niezamierzone konwersje typów danych: stąd pochodzi bit „jest wolniejszy”

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

Wszystkie typy danych są takie same, nie zobaczysz żadnej praktycznej różnicy ...

42
gbn

Jak zauważył Mark, ciężko będzie znaleźć różnice w wydajności; Myślę, że inne czynniki będą ważniejsze. Dla mnie ja zawsze używam COALESCE, a większość z nich została już wspomniana przez ciebie lub Marka:

  • COALESCE jest standardem ANSI. To jedna mniejsza rzecz, o którą muszę się martwić, jeśli zamierzam przenieść swój kod. Dla mnie osobiście nie jest to tak ważne, ponieważ wiem, jak często takie porty zdarzają się poza światem klasy Celko, ale dla niektórych osób jest to korzyść.
  • W przeciwieństwie do tego, co powiedziałeś o czytelności, uważam, że trudniej jest czytać ISNULL, szczególnie dla użytkowników pochodzących z innych języków lub platform, na których ISNULL zwraca wartość logiczną ( który nie istnieje w SQL Server). To prawda, że ​​COALESCE trudniej jest przeliterować, ale przynajmniej nie prowadzi to do błędnych założeń.
  • COALESCE jest o wiele bardziej elastyczny, jak mogę powiedzieć COALESCE (a, b, c, d), podczas gdy z ISNULL musiałbym dużo zagnieżdżać, aby osiągnąć to samo.

Należy również upewnić się, że użytkownik jest świadomy sposobu, w jaki pierwszeństwo typu danych jest obsługiwane przy użyciu dwóch funkcji, jeśli używa się go z różnymi typami danych/dokładnościami itp.

Uwaga

Jest jeden wyjątek. Są one obsługiwane inaczej w bieżących wersjach SQL Server:

SELECT COALESCE((SELECT some_aggregate_query),0); 

SELECT ISNULL((SELECT some_aggregate_query),0); 

Wariant COALESCE faktycznie wykona some_aggregate_query Dwa razy (raz, aby sprawdzić wartość i raz, aby zwrócić ją, gdy nie jest zero), natomiast ISNULL wykona podzapytanie tylko raz. Mówię tutaj o kilku innych różnicach:

24
Aaron Bertrand