Lequel est le plus rapide COALESCE OU ISNULL?

Je comprends la différence entre ces fonctions, mais ma question est de vérifier si une seule valeur nulle serait ISNULL plus rapide que l'utilisation de COALESCE?

par exemple

COALESCE(SELECT TOP 1 SomeValue FROM SomeTable, 0) 

contre

 ISNULL(SELECT TOP 1 SomeValue FROM SomeTable, 0) 

J'ai eu un rapide coup d'œil, car il est intéressant de voir un certain nombre de comparaisons différentes sur la performance entre les deux. Je pense que cet article de Adam Machanic est le plus précis dans l'parsing de performance effectuée sur ce sujet. :

… et ISNULL semble surpasser constamment COALESCE de 10 à 12% en moyenne

Cependant, je partage le même sharepoint vue que ce qu'il dit ensuite – que la différence est assez négligeable – par exemple, dans ses tests, un million d'exécutions a montré en moyenne une différence de 0,7 seconde. Est-ce que ça vaut le coup? Je dirais qu'il y a probablement des zones plus grandes à optimiser. Mais lisez l'article, c'est une bonne lecture.

Dans ce cas, ISNULL est la meilleure option. Parce que SQL Server interprète la fonction COALESCE comme une instruction CASE. Donc, votre requête

COALESCE (SÉLECTIONNER TOP 1 SomeValue FROM SomeTable, 0)

sera écrit par SQL Server comme

  1. CAS
  2. QUAND ( SELECT TOP 1 SomeValue FROM SomeTable ) N'EST PAS NUL
  3. ALORS ( SELECT TOP 1 SomeValue FROM SomeTable )
  4. SINON 0
  5. FIN

Si vous observez l'interprétation ci-dessus, "SomeTable" sera scanné deux fois. Mais ISNULL ne sera évalué qu'une seule fois.

ISNULL sera plus rapide je pense, car il a une implémentation de code / fonction moindre pour lui-même, ce qui le rend plus rapide que COALESCE

Veuillez cocher le lien pour préférer ISNULL sur COALESCE quand vous COALESCE le choix, ISNULL tendance à produire des plans de requête plus efficaces que COALESCE .

  1. ISNULL Vs COALESCE

  2. Test de vitesse ISNULL vs COALESCE

  3. S'il vous plaît vérifier la performance : ISNULL vs COALESCE

Pour ce qui est de sa valeur Vous avez un cas d'utilisation très spécifique, j'ai donc utilisé un exemple de votre question sur le premier en valeur sur une table qui est venu à l'esprit et contrôlé le script pour d'autres variables. J'ai supposé que someval était un int comme vous avez utilisé 0. Ma suggestion est que vous choisissiez votre cas spécifique someval / sometable et fassiez le test vous-même.

 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); 

Les résultats ont été assez spectaculaires, 11270 pour isnull et 18930 pour coalesce. Inversion de l'ordre des loops comme un deuxième test produit 18260 pour coalesce et 10810 pour isnull. Pour votre cas particulier, je dirais qu'isnull est clairement plus rapide.

Cela ne veut pas dire que c'est mieux dans toute autre situation donnée. L'utilisation de valeurs directes, ou de nvarchars ou de bits au lieu de int, ou d'une colonne qui n'est pas une key primaire, ou l'option Imbrication par rapport à l'ajout de parameters à merge peut changer les choses.

Cela répond uniquement à la question telle qu'elle a été posée.

Je viens de passer un test sur mon propre DB. Environ 700k lignes.

 SELECT COUNT(*) FROM table WHERE COALESCE(field_1,field_2,field_3,field_4) IS NOT NULL 

Résultat de 12106 obtenu en 56 secondes.

 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 

Résultat de 12106 obtenu en 0.00 secondes.