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
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
.
ISNULL Vs COALESCE
Test de vitesse ISNULL vs COALESCE
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.