Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 08/02/2011, 15h30   #1
Invité de passage
 
Inscription : juin 2006
Messages : 8
Détails du profil
Informations forums :
Inscription : juin 2006
Messages : 8
Points : 0
Points : 0
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 :
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 !
Socap est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2011, 15h38   #2
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
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 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
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...
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 09/02/2011, 10h55   #3
Invité de passage
 
Inscription : juin 2006
Messages : 8
Détails du profil
Informations forums :
Inscription : juin 2006
Messages : 8
Points : 0
Points : 0
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 ?
Socap est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2011, 10h56   #4
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
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 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Tout dépend de votre architecture matériel (RAM, CPU, DISQUE...)
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 09/02/2011, 11h00   #5
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
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 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
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?
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 09/02/2011, 11h40   #6
Invité de passage
 
Inscription : juin 2006
Messages : 8
Détails du profil
Informations forums :
Inscription : juin 2006
Messages : 8
Points : 0
Points : 0
Voici le plan d'exécution réel :



Et les stats I/O :

Citation:
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 :
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.
Socap est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2011, 14h01   #7
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
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 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Le nombre d'io me parait important pour un index couvrant dont la clé d'index est une FK (soit dis en passant: vu le résultat vos données n'étaient pas en cache (lectures physique: jouez la requête deux fois de suite))?

Peut-on voir la structure de vos table(typages etc.)

Autre question : dans quel cadre utilisez vous cette requête? je doute que vous vouliez afficher plusieurs million de lignes comme çà?
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 07h58.


 
 
 
 
Partenaires

Hébergement Web