IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

ISNULL ou COALESCE ? [2008R2]


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert

    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2007
    Messages
    3 530
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 530
    Par défaut ISNULL ou COALESCE ?
    Bonjour,

    Si j'ai tout compris (oui j'ai free), ISNULL et COALESCE sont équivalents, mis à part le nombre de paramètres. Mais est-ce qu'il y a une différence de performance entre les deux quand on peut utiliser l'une ou l'autre ?

    Papy !

  2. #2
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Bonjour Papy214,

    Il n'y a aucune différence de performances : l'opérateur qui implémente ces deux fonctions est le même.
    En revanche ISNULL() est T-SQL, alors que COALESCE() fait partie du Standard SQL.

    @++

  3. #3
    Membre Expert

    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2007
    Messages
    3 530
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 530
    Par défaut
    Merci, bon w-e

  4. #4
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Bonjour,

    Citation Envoyé par elsuket Voir le message
    l'opérateur qui implémente ces deux fonctions est le même.
    Je ne suis pas tout à fait d'accord :
    Lors de l'utilisation de paramètre hétérogènes, ISNULL transtype le second paramètre vers le type du premier (ISNULL n'accepte que deux arguments) alors que COALESCE transtype en suivant les règles de précédence.

    Je n'ai pas fait de test, mais je pense effectivement que la différence de performance, s'il y en a, doit etre insignifiante.
    Par contre la différence de comportement peut avoir des conséquences :
    Exemple 1 /
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    DECLARE @a VARCHAR(3)
     
    SELECT ISNULL(@a, 'abcdef') AS Result_ISNULL, COALESCE(@a, 'abcdef') Result_COALESCE
    --Result_ISNULL 	Result_COALESCE
    --abc 			abcdef
    Ici, ISNULL a transtypé implicitement 'abcdef' vers un VARCHAR(3)


    Exemple 2/
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    DECLARE @a VARCHAR(3) = 'a'
    DECLARE @b INT
     
    SELECT ISNULL(@a, @b) --> renvoit 'a'
     
    SELECT COALESCE(@a, @b)	--> erreur : Échec de la conversion de la valeur varchar 'a' en type de données int.

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 999
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 999
    Billets dans le blog
    6
    Par défaut
    D’après mes tests COALESCE est légèrement plus rapide...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    USE tempdb;
    GO
     
    CREATE TABLE T_TEST
    (FONCTION   VARCHAR(8),
     DEBUT      DATETIME2(7),
     FIN        DATETIME2(7),
     DATA       INT)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    SET NOCOUNT ON;
    GO
     
    INSERT INTO T_TEST VALUES ('ISNULL',  SYSDATETIME(), NULL, NULL);
    GO
     
    DECLARE @I INT;
    SET @I = 0
    WHILE @I < 100000
    BEGIN
       UPDATE T_TEST SET DATA = ISNULL(NULL, 1) WHERE FONCTION = 'ISNULL';
       SET @I += 1;
    END
    GO
     
    UPDATE T_TEST SET FIN = SYSDATETIME() WHERE FONCTION = 'ISNULL';
    GO
     
    INSERT INTO T_TEST VALUES ('COALESCE',  SYSDATETIME(), NULL, NULL);
    GO
     
    DECLARE @I INT;
    SET @I = 0
    WHILE @I < 100000
    BEGIN
       UPDATE T_TEST SET DATA = COALESCE(NULL, 1) WHERE FONCTION = 'COALESCE';
       SET @I += 1;
    END
    GO
     
    UPDATE T_TEST SET FIN = SYSDATETIME() WHERE FONCTION = 'COALESCE';
    GO
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT FONCTION, DATEDIFF(ms, DEBUT, FIN) AS DUREE_ms
    FROM T_TEST
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    FONCTION DUREE_ms
    -------- -----------
    ISNULL   8563
    COALESCE 7104
    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  6. #6
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    D’après mes tests COALESCE est légèrement plus rapide...
    Ton test chez moi donne un COALESCE 30% plus lent...

    Par contre :

    Je n'ai pas fait de test,
    J'ai pas pu m'empecher...

    mais je pense effectivement que la différence de performance, s'il y en a, doit être insignifiante.
    pas toujours en fait, et je confirme que COALESCE n'utilise pas le même algo que ISNULL :
    COALESCE semble remplacer purement et simplement par un CASE WHEN...Ce qui n'est pas le cas de ISNULL : on peut même avoir des plans d’exécution différents :

    Jeu de données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
     
    SET STATISTICS IO, TIME OFF
    IF OBJECT_ID('B', 'U') IS NOT NULL DROP TABLE B
    IF OBJECT_ID('A', 'U') IS NOT NULL DROP TABLE A
     
     
    CREATE TABLE A(
    		id		INT NOT NULL PRIMARY KEY IDENTITY
    	,	val		VARCHAR(50)
    )
     
    CREATE TABLE B(
    		id		INT NOT NULL PRIMARY KEY IDENTITY
    	,	id_A	INT NOT NULL FOREIGN KEY REFERENCES A(id)
    	,	val		VARCHAR(50)
    )
     
    GO
     
    SET NOCOUNT ON
    INSERT INTO A(val) VALUES(newid())
    GO 1000
     
    INSERT INTO B(id_A, val)
    	SELECT TOP(10) PERCENT id , NEWID()
    	FROM	 A 
    	ORDER BY NEWID()
    GO 100000
     
     
    DELETE FROM B 
    WHERE id_A IN (SELECT TOP(60) PERCENT id FROM A)
     
    UPDATE TOP(60) PERCENT B SET val = NULL
     
    CREATE UNIQUE INDEX UIX_VAL ON A(val)
    requêtes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
     
    SET STATISTICS IO, TIME ON
     
     
    SELECT	ISNULL(
    				(SELECT MAX(val) FROM B WHERE id_A = A.id)
    			,	(SELECT MAX(val) FROM B)
    		)
    FROM	A
     
    SELECT	COALESCE(
    				(SELECT MAX(val) FROM B WHERE id_A = A.id)
    			,	(SELECT MAX(val) FROM B)
    		)
    FROM	A
    Avec ISNULL :
    Table 'Worktable'. Nombre d'analyses 0, lectures logiques 0, lectures physiques 0,...
    Table 'B'. Nombre d'analyses 2, lectures logiques 141372, lectures physiques 0,...
    Table 'A'. Nombre d'analyses 1, lectures logiques 9, lectures physiques 0,...

    SQL Server \endash Temps d'exécution*:
    , Temps UC = 3369*ms, temps écoulé = 3440*ms.
    Avec COALESCE :
    Table 'Worktable'. Nombre d'analyses 400, lectures logiques 12044579, lectures physiques 0, ...
    Table 'B'. Nombre d'analyses 3, lectures logiques 212058, lectures physiques 0,...
    Table 'A'. Nombre d'analyses 1, lectures logiques 9, lectures physiques 0, ...

    SQL Server \endash Temps d'exécution*:
    , Temps UC = 24212*ms, temps écoulé = 24384*ms.
    COALESCE est très largement contre performant (certes la requête aussi, mais c'est pour l'exemple) : presque 8 fois plus lent, et 85 fois plus d'io qu'avec ISNULL...

  7. #7
    Membre Expert

    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2007
    Messages
    3 530
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 530
    Par défaut
    Étant encore loin du niveau des spécialistes que vous êtes, je vais préférer COALESCE puisque c'est le standard SQL.

    Mais ces tests sont forts intéressants. Merci à vous tous

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. différence entre isnull et coalesce
    Par mdevlieg dans le forum Langage SQL
    Réponses: 5
    Dernier message: 15/05/2009, 11h45
  2. [Sybase]fonction isnull
    Par SB44 dans le forum Sybase
    Réponses: 2
    Dernier message: 29/12/2004, 11h24
  3. [coalesce]probleme de requete
    Par Snowballz dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 15/10/2004, 15h32
  4. [ACESS][MEMO][ISNULL]Comportement bizarre
    Par seb.49 dans le forum ASP
    Réponses: 2
    Dernier message: 09/06/2004, 10h44
  5. Fonction COALESCE
    Par sbeu dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 08/01/2004, 14h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo