Différence de performance entre COALESCE et ISNULL?


48

J'ai vu beaucoup de gens utiliser la fonction COALESCE à la place de ISNULL. Des recherches sur Internet, j'ai constaté que COALESCE est conforme à la norme ANSI. Nous avons donc un avantage: nous savons à quoi nous attendre lorsque nous l'utilisons. Cependant, ISNULL semble plus facile à lire puisqu'il semble plus clair ce que cela fait.

Je réalise aussi 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.

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


1
Je ne vois aucune mention dans les réponses qu'une sous-requête dans un objet COALESCE soit évaluée deux fois.
Martin Smith

4
"ISNULL semble plus facile à lire puisqu'il semble plus clair ce qu'il fait" - vraiment? Je trouve le nom contre-intuitif: je m'attendrais à ce qu'il renvoie un booléen indiquant si une expression résolue est nulle ou inconnue. Le nom COALESCEn’est pas intuitif;)
quand le

Réponses:



40
  • ISNULL est spécifique à Sybase / SQL Server
  • COALESCE est portable

ensuite

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

Enfin, et le bit amusant. Le type de données de résultat 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 que COALESCE peut ajouter des conversions de type de données inattendues: d'où provient 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 ...


22

Comme Mark l'a souligné, vous aurez du mal à trouver des différences de performances; Je pense que d'autres facteurs seront plus importants. Pour moi, j'utilise toujours 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 vais transférer mon code. Pour moi personnellement, ce n’est pas très important, car je sais qu’il est rare que de tels ports se produisent réellement en dehors du monde de la classe de Celko, mais pour certains, c’est un avantage.
  • Contrairement à ce que vous avez dit sur la lisibilité, je trouve qu'il peut être 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, car je peux dire COALESCE (a, b, c, d) alors qu'avec ISNULL, je devrais faire beaucoup d'imbrication pour obtenir le même résultat.

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

Remarque

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

SELECT COALESCE((SELECT some_aggregate_query),0); 

SELECT ISNULL((SELECT some_aggregate_query),0); 

La COALESCEvariante sera en fait exécutée some_aggregate_querydeux fois (une fois pour vérifier la valeur et une fois pour la renvoyer si non nulle), alors ISNULLque la sous-requête ne sera exécutée qu'une fois. Je parle ici de quelques autres différences:

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.