web-dev-qa-db-fra.com

Différence de performances entre COALESCE et ISNULL?

J'ai vu beaucoup de gens utiliser la fonction COALESCE à la place d'ISNULL. D'après les recherches sur Internet, j'ai trouvé que COALESCE est la norme ANSI, il y a donc un avantage à savoir à quoi s'attendre lors de son utilisation. Cependant, ISNULL semble plus facile à lire car il semble plus clair ce qu'il fait.

Je me rends également compte que ISNULL est un peu délicat car il agit différemment sur différents serveurs de bases de données et dans différentes langues.

Tout cela, dans mon esprit, se résume au style et aux normes. Étant donné que le style est subjectif, y a-t-il une raison d'utiliser COALESCE sur ISNULL (ou vice versa)? Plus précisément, y a-t-il un avantage de performance l'un par rapport à l'autre?

51
Richard

COALESCE est traduit en interne en une expression CASE, ISNULL est une fonction de moteur interne.

COALESCE est une fonction standard ANSI, ISNULL est T-SQL.

Des différences de performances peuvent survenir et surviennent lorsque le choix influe sur le plan d'exécution mais la la différence de vitesse de la fonction brute est minuscule .

28
Mark Storey-Smith
  • ISNULL est spécifique à Sybase/SQL Server
  • COALESCE est portable

Alors

  • ISNULL prend 2 arguments
  • COALESCE prend des arguments 1-n

Enfin, et le peu de plaisir. Le type de données résultant et la longueur/précision/échelle

Ce dernier bit est la raison pour laquelle ISNULL est généralement utilisé car il est plus prévisible (?) Et COALESCE peut ajouter des conversions de types de données involontaires: d'où vient le bit "c'est plus lent"

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

Tous les types de données étant identiques, vous ne verrez aucune différence pratique ...

42
gbn

Comme l'a souligné Mark, vous allez avoir du mal à trouver des différences de performances; Je pense que d'autres facteurs seront plus importants. Pour moi, je toujours utilise COALESCE, et la plupart de cela a déjà été mentionné par vous ou Mark:

  • COALESCE est la norme ANSI. C'est une chose de moins dont je dois m'inquiéter si je veux porter mon code. Pour moi, ce n'est pas si important, car je sais à quel point ces ports se produisent rarement en dehors du monde de la classe de Celko, mais pour certaines personnes, c'est un avantage.
  • Contrairement à ce que vous avez dit sur la lisibilité, je trouve qu'il est plus difficile de lire ISNULL, en particulier pour les utilisateurs provenant d'autres langues ou plates-formes où ISNULL renvoie un booléen ( qui n'existe pas dans SQL Server). Certes, COALESCE est plus difficile à épeler, mais au moins cela ne conduit pas à des hypothèses incorrectes.
  • COALESCE est beaucoup plus flexible, comme je peux dire COALESCE (a, b, c, d) alors qu'avec ISNULL je devrais faire beaucoup d'imbrication pour arriver à la même chose.

Vous devez également être sûr de savoir comment la priorité des types de données est gérée à l'aide des deux fonctions si vous l'utilisez avec différents types de données/précisions, etc.

Remarque

Il y a une exception. Celles-ci sont gérées différemment dans les versions actuelles de SQL Server:

SELECT COALESCE((SELECT some_aggregate_query),0); 

SELECT ISNULL((SELECT some_aggregate_query),0); 

La variante COALESCE exécutera réellement some_aggregate_query deux fois (une fois pour vérifier la valeur et une fois pour la renvoyer lorsqu'elle est différente de zéro), tandis que ISNULL n'exécutera la sous-requête qu'une seule fois. Je parle ici de quelques autres différences:

24
Aaron Bertrand