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 :

Tuning SQL - Jointure complète


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 8
    Par défaut Tuning SQL - Jointure complète
    Bonjour,

    J'ai une requête qui prend, à mon avis, trop de temps à d'exécuter par rapport à ce qu'il pourrait en être avec une véritable optimisation. Voici la requête en question, qui s'exécute en un peu plus de 2 minutes :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    select
      A.idA,
      B.idB,
      A.champDetail1,
      B.champDetail2
    from A inner join B
    on A.idB = B.idB
    La table A contient environ 16 millions d'enregistrements, tandis que B en contient 3 millions.
    A.idA est la PK de A, et B.idB est la PK de B. Il y a sémantiquement une relation de clé étrangère entre A.idB et B.idB, mais, pour des raisons annexes, cette clé étrangère n'est pas implémentée.
    La colonne A.idB a cependant été indexée (nonclustered, autres options par défaut).

    Voici l'explain plan de la requête :



    Je ne comprends pas pourquoi un scan de la PK de A est réalisé, plutôt qu'un scan de l'index positionné sur A.idB.

    Un update statistics a évidemment été réalisé manuellement sur A ainsi que B.

    Je ne suis pas un spécialiste du tuning SQL-Server, et j'ai uniquement quelques notions de base sous Oracle.

    Merci pour votre aide, je reste à votre disposition pour toute info nécessaire !

  2. #2
    Membre Expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Par défaut
    Vous avez un index sur idB (table A)mais il ne permet pas à SQL SERVER de couvrir votre requête puisqu'il doit chercher dans son index cluster (IDA table A) les colonnes champ1 et IDA(tout deux présents dans le SELECT).

    SQL doit estimer que le cout de recherche dans l'index cluster est plus lourd que de parcourir votre index sur IDB...

    Tout dépend également de la dispersion de IDB dans votre table A...
    Crée un index sur A.IDB avec en colonne include champ1 et IDA:

    CREATE NONCLUSTERED INDEX IX_IDB ON A (IDB) INCLUDE (champDetail1,IDA)
    Vous obtenez un index parfaitement couvrant pour la table A de la requete...

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 8
    Par défaut
    Merci pour cette explication. Effectivement, la création de cet index permet son utilisation dans la requête soumise.

    Par contre, côté perfs, j'ai le même temps d'exécution qu'avant, donc pas de réelle avancée par rapport à mon problème initial.

    Est-ce que ce temps d'exécution semble cohérent ?

  4. #4
    Membre Expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Par défaut
    Tout dépend de votre architecture matériel (RAM, CPU, DISQUE...)

  5. #5
    Membre Expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Par défaut
    Pouvez vous montrer le nouveau plan d’exécution?Le détails des IO (SET STATISTICS IO ON)


    Nous avons parlé de la TABLE A mais il vous manque clairement le même genre d'index sur la TABLE B...

    Gardez en outre à l'esprit que si vous remontez plusieurs millions de lignes dans votre SELECT, le résultat de la requête est remonté via le réseau.... d'ou un temps important dû au transit du résultat sur votre poste.

    D'où effectuez vous la requête? sur le Server hébergeant votre SGBD? sur un poste client avec SSMS?

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 8
    Par défaut
    Voici le plan d'exécution réel :



    Et les stats I/O :

    Table 'A'. Nombre d'analyses 1, lectures logiques 91862, lectures physiques 1019, lectures anticipées 69909, lectures logiques de données d'objets volumineux 0, lectures physiques de données d'objets volumineux 0, lectures anticipées de données d'objets volumineux 0.
    Table 'B'. Nombre d'analyses 1, lectures logiques 28186, lectures physiques 4230, lectures anticipées 18844, lectures logiques de données d'objets volumineux 0, lectures physiques de données d'objets volumineux 0, lectures anticipées de données d'objets volumineux 0.
    La requête est effectivement exécutée depuis un client ssms distant. Mais je suis allé l'exécuter directement sur le ssms installé sur le serveur bdd, et le temps d'exécution était le même.

    J'ai également testé la création d'un index similaire sur B :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    create nonclustered index idx_B on B (idB) include (champDetail2)
    Et voici le nouvel explain plan :



    Mais le temps d'exécution reste le même.

Discussions similaires

  1. Tuning Sql & jointure
    Par Stef784ever dans le forum SQL
    Réponses: 3
    Dernier message: 11/05/2010, 15h59
  2. [SQL] jointure externe complète
    Par kirgan dans le forum Access
    Réponses: 2
    Dernier message: 15/05/2006, 13h07
  3. [SQL] Jointure,Group BY et ORDER BY COUNT qui marche pas
    Par Stef784ever dans le forum Langage SQL
    Réponses: 8
    Dernier message: 17/08/2005, 12h28
  4. [SQL] jointure externe avec 3 tables, comment faire ....
    Par grumbok dans le forum Langage SQL
    Réponses: 2
    Dernier message: 04/08/2005, 16h13
  5. [sql] [jointure] champs = substring(champs,1,5)
    Par DaxTaz dans le forum Langage SQL
    Réponses: 2
    Dernier message: 26/05/2004, 12h45

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