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 :

Optimisation requête contenant la fonction ISNULL()


Sujet :

Développement SQL Server

  1. #1
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2007
    Messages
    169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2007
    Messages : 169
    Points : 241
    Points
    241
    Par défaut Optimisation requête contenant la fonction ISNULL()
    Bonjour,

    J'ai une requête que je voudrais optimiser. Celle ci fait le lien entre plusieurs tables (contenant des centaines de milliers d'enregistrements) et effectue des comparaisons sur plusieurs champs.

    Pour résumer mon problème, je vais prendre un exemple simplifié.
    Disons que j'ai une table TB_ADRESSES (id_adresse, rue, numeroMaison, codePostal) contenant des adresses indexée sur tous les champs.
    Je veux voir quelles adresses sont équivalentes, c'est à dire même 'rue', même 'numeroMaison' et même 'codePostal'.

    Pour cela je pourrais faire quelque chose du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT TB1.id_adresse, TB2.id_adresse
    FROM TB_ADRESSES  AS TB1, TB_ADRESSES AS TB2
    WHERE TB1.rue = TB2.rue
    AND TB1.numeroMaison = TB2.numeroMaison
    AND TB1.codePostal = TB2.codePostal

    Mon problème est que certains champs peuvent être nuls. Et dans ce cas ci la requête ne fonctionne pas correctement..!
    Pour y remédier, j'utilise la fonction IsNull.

    Il me faut alors mettre le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT TB1.id_adresse, TB2.id_adresse
    FROM TB_ADRESSES  AS TB1, TB_ADRESSES AS TB2
    WHERE IsNull(TB1.rue,'(null)') = IsNull(TB2.rue,'(null)')
    AND IsNull(TB1.numeroMaison,'(null)') = IsNull(TB2.numeroMaison,'(null)')
    AND IsNull(TB1.codePostal,'(null)') = IsNull(TB2.codePostal,'(null)')
    Dans ce cas ça marche, mais le requête devient beaucoup moins performante.
    Si je ne trompe pas, ceci peut être en partie expliqué par le fait que les indexes sur les champs rue, numéroMaison et codePostal ne sont plus utilisés (?).

    => Comment est ce que je peux modifier cette requête pour optimiser sa performance?

    Merci par avance pour vos conseils!
    Lionel Garnier

    N'oubliez pas de voter pour les posts en cliquant sur le
    Cliquez sur le bouton lorsque vous êtes satisfaits de la réponse!
    mon site pro

  2. #2
    Membre actif
    Inscrit en
    Janvier 2012
    Messages
    145
    Détails du profil
    Informations forums :
    Inscription : Janvier 2012
    Messages : 145
    Points : 226
    Points
    226
    Par défaut
    Comment peut on avoir 2 adresses avec même numéro, même rue et même CP? L'ID_ADRESSE n'est il pas là pour identifier de manière unique une adresse?

    Sinon, peux tu tester ceci?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT TB1.id_adresse, TB2.id_adresse
    FROM TB_ADRESSES  AS TB1, TB_ADRESSES AS TB2
    WHERE (TB1.rue = TB2.rue OR (TB1.rue IS NULL AND TB2.rue IS NULL)) AND
          (TB1.numeroMaison = TB2.numeroMaison  OR (TB1.numeroMaison IS NULL AND TB2.numeroMaison IS NULL)) AND
          (TB1.codePostal = TB2.codePostal  OR (TB1.codePostal IS NULL AND TB2.codePostal IS NULL))

  3. #3
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2007
    Messages
    169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2007
    Messages : 169
    Points : 241
    Points
    241
    Par défaut
    Merci pour la réponse

    Ici j'ai pris un exemple simplifié donc il ne faut pas trop faire attention au sens de la requête! Par exemple il se pourrait que la table adresse ai d'autres champs (étage, porte...).

    Je vais faire quelques tests pour voir si la requête s’exécute plus rapidement ainsi!
    Lionel Garnier

    N'oubliez pas de voter pour les posts en cliquant sur le
    Cliquez sur le bouton lorsque vous êtes satisfaits de la réponse!
    mon site pro

  4. #4
    Membre émérite

    Homme Profil pro
    Chargé de Développement et d'Analyse de données
    Inscrit en
    Mars 2010
    Messages
    1 278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Chargé de Développement et d'Analyse de données
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 278
    Points : 2 856
    Points
    2 856
    Par défaut
    Utiliser la fonction CASE au lieu de ISNULL.

    ISNULL ce n'est pas du SQL !
    Etienne ZINZINDOHOUE
    Billets-Articles

  5. #5
    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 : 42
    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
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Si la modélisation n'était pas fausse (dans le sens où elle ne répond visiblement pas à votre besoin), probablement qu'écrire la requête serait non seulement plus simple mais aussi plus performant

    Si je ne trompe pas, ceci peut être en partie expliqué par le fait que les indexes sur les champs rue, numéroMaison et codePostal ne sont plus utilisés (?).
    Pas forcément, il peuvent être entièrement balayés (scan) au lieu d'être recherchés (seek).
    Cela est dû au fait que par les statistiques sous-jacentes aux indexes et à celles créées automatiquement par SQL Server, le moteur de base de données est capable de déterminer convenablement combien de lignes vont vérifier un prédicat, mais pas l'un OU l'autre.
    Une voie d'optimisation est la réécriture de la requête avec UNION, une requête traitant les lignes dont les colonnes ont une valeur, et l'autre les autres.
    Avec SQL Server 2008, vous pouvez également avoir recours aux index filtrés.

    Enfin si vos adresses étaient uniques (contrainte d'unicité), le problème ne se serait pas posé

    Citation Envoyé par zinzinetti
    ISNULL ce n'est pas du SQL !
    Donne l'alternative : COALESCE()

    @++

  6. #6
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Octobre 2007
    Messages
    169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2007
    Messages : 169
    Points : 241
    Points
    241
    Par défaut
    Merci pour vos réponses.

    Pour info, j'ai effectué quelques tests. La fonction COALESCE() est en effet un peu plus rapide que la fonction ISNULL() bien que ce ne soit pas flagrant non plus! (15% plus rapide).

    J'ai aussi testé les autres solutions proposées mais elle ne se sont pas montrées plus performantes.


    Au niveau de l'unicité des adresses, je suis à 100% d'accord avec vous. Mais mon programme vient chercher les infos dans une base existante sur laquelle je n'ai aucun contrôle! (SAP du client) Je dois donc faire avec...
    Lionel Garnier

    N'oubliez pas de voter pour les posts en cliquant sur le
    Cliquez sur le bouton lorsque vous êtes satisfaits de la réponse!
    mon site pro

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

Discussions similaires

  1. Optimisation d'une requête contenant des sous-requêtes
    Par Christophe Charron dans le forum Requêtes
    Réponses: 2
    Dernier message: 28/06/2010, 15h34
  2. optimisation requête
    Par alex2205 dans le forum Décisions SGBD
    Réponses: 5
    Dernier message: 09/02/2005, 14h15
  3. [Requête] Problème avec fonction "DATE_FORMAT()"
    Par sekiryou dans le forum Requêtes
    Réponses: 4
    Dernier message: 11/01/2005, 21h52
  4. [Sybase]fonction isnull
    Par SB44 dans le forum Sybase
    Réponses: 2
    Dernier message: 29/12/2004, 11h24
  5. optimisation requête SQL!!! help!!
    Par anathem62 dans le forum Requêtes
    Réponses: 2
    Dernier message: 24/05/2004, 16h26

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