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 10/05/2011, 12h48   #1
Invité de passage
 
Femme
Développeur décisionnel
Inscription : mai 2011
Messages : 10
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Développeur décisionnel
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 10
Points : 0
Points : 0
Par défaut Optimisation de requête sous SQL Server

Bonjour,

Habituée d'Oracle, je découvre SQL-Server.
J'ai un modèle en étoile avec un table de fait d'environ 20 millions d'enregistrements et une centaine de colonnes qui sont des id de tables de référence. Ces tables de référence contiennent entre 2 et 10 enregistrements.
Je construit une requête du type :
Requête 1 :
Code :
1
2
3
4
5
6
7
8
9
SELECT TR1.libelle, 
         TR2.libelle, 
         count(DISTINCT TF.PrimaryKeyId)
FROM TF 
INNER JOIN TR1 ON (TF.TR1_ID=TR1.TR1_ID)
INNER JOIN TR2 ON (TF.TR2_ID=TR2.TR2_ID)
WHERE TF.TR3_ID=1
GROUP BY TR1.libelle, 
         TR2.libelle;
Requête 2 :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
SELECT TR1.libelle, 
         TR2.libelle, 
         TR4.libelle, 
         count(DISTINCT TF.PrimaryKeyId)
FROM TF 
INNER JOIN TR1 ON (TF.TR1_ID=TR1.TR1_ID)
INNER JOIN TR2 ON (TF.TR2_ID=TR2.TR2_ID)
INNER JOIN TR4 ON (TF.TR4_ID=TR4.TR4_ID)
WHERE TF.TR3_ID=1
GROUP BY TR1.libelle, 
         TR2.libelle, 
         TR4.libelle;
A chaque libelle de table de référence que j'ajoute dans ma requête, il s'ajoute 2mn30 au temps d'exécution.
Ainsi la requête 2 met 2mn30 de plus que la requête 1.

Dans Oracle, l'ajout de libellés de tables de référence dans le SELECT n'a aucune influence sur les temps d'exécution ?! Donc je cherche à comprendre pourquoi c'est différent sous SQL-Server.

J'ai testé la requête sans jointure et les performances sont bonnes.
Ce sont donc les jointures avec les tables de référence de qqs lignes qui ralentissent fortement le temps d'exécution.
Pouvez-vous m'expliquer pourquoi ? Et comment faire pour que ce ne soit pas le cas ?

Avec mes remerciements,
Pitchoonet
Pitchoonet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 13h51   #2
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 953
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 953
Points : 17 773
Points : 17 773
C'est un problématique de star join. Quelle version /édition de SQL Server ? (2005, 20088 enterpriss, standard.... ?
base relationnelle ou décisionnelle. ???
Évidemment ce serait mieux si c'était déjà un cube décisionnel !

A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 13h52   #3
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 668
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

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

Informations forums :
Inscription : janvier 2005
Messages : 4 668
Points : 8 718
Points : 8 718
Bonjour,

Citation:
J'ai un modèle en étoile avec un table de fait d'environ 20 millions d'enregistrements et une centaine de colonnes qui sont des id de tables de référence
Vous confondez modèle relationnel et analytique.

Citation:
Dans Oracle, l'ajout de libellés de tables de référence dans le SELECT n'a aucune influence sur les temps d'exécution?! Donc je cherche à comprendre pourquoi c'est différent sous SQL Server.
Ça me paraît un peu gros ...
Je suppose que vous avez les mêmes structures de table, mais avez-vous exactement les mêmes index ?

Si c'est le cas, il vous faut voir d'où l'activité disque provient, à l'aide de l'option de session SET STATISTICS IO ON :

Code :
1
2
3
4
SET STATISTICS IO ON
GO
 
script ...
Vous trouverez le nombre de pages lues par table dans l'onglet Messages de SQL Server Management Studio (SSMS) après exécution de la requête.

Prenez aussi le plan de requête réel, qui vous décrira ce que fait SQL Server.
Pour cela, il vous suffit d'activer son exposition :



Il sera affiché dans un nouvel onglet nommé Execution Plan.
Vous pouvez le sauvegarder en cliquant-droit sur celui-ci, et le poster ici ensuite (si cela vous est autorisé )

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 14h03   #4
Invité de passage
 
Femme
Développeur décisionnel
Inscription : mai 2011
Messages : 10
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Développeur décisionnel
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 10
Points : 0
Points : 0
Par défaut A SQLPro

Merci pour votre aide.

Version :
Microsoft SQL Server Enterprise Edition (64-bit) 2008 R2

Base de données relationnelle

Pitchoonet
Pitchoonet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 14h19   #5
Invité de passage
 
Inscription : novembre 2010
Messages : 4
Détails du profil
Informations forums :
Inscription : novembre 2010
Messages : 4
Points : 4
Points : 4
bonjour,
En plus de ce que vous a dit elsuket essayer de modifiant la requête comme ci-dessous, et comparer les plan d'executions avec votre requête d'origine.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT 
MIN(TR1.libelle) AS TR1_Libelle, 
MIN(TR2.libelle) AS TR2_Libelle, 
MIN(TR4.libelle) AS TR4_Libelle, 
count(DISTINCT TF.PrimaryKeyId)
FROM TF 
INNER JOIN TR1 ON (TF.TR1_ID=TR1.TR1_ID)
INNER JOIN TR2 ON (TF.TR2_ID=TR2.TR2_ID)
INNER JOIN TR4 ON (TF.TR4_ID=TR4.TR4_ID)
WHERE TF.TR3_ID=1
GROUP BY 
TF.TR1_ID, 
TF.TR2_ID, 
TF.TR4_ID;
TheGuepard est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 18h25   #6
Invité de passage
 
Femme
Développeur décisionnel
Inscription : mai 2011
Messages : 10
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Développeur décisionnel
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 10
Points : 0
Points : 0
Grâce à votre aide, j'ai pu identifier 2 facteurs de ralentissement de ma requête :
- le passage de 9 à 10 jointures avec des tables de référence : ma requête passe de 1mn30 à 8mn. J'ai essayer avec plusieurs jointures différentes afin d’identifier si le facteur discriminant était le nombre de jointures ou la volumétrie ramenée et j'obtiens donc 1mn30 d'exécution en ramenant 230 000 lignes et 8mn en ramenant 130 000 lignes.
Svp, existe-t-il une limitation de ce type à votre connaissance?

- l'utilisation d'un case dans ma fonction d'agrégation : count(distinct case when TF.TR_ID=1 then TF.PrimaryKeyId end)

J'imagine que le second facteur discriminant doit pouvoir se résoudre avec des indexs.
Svp, avez-vous des recos?

Avec mes remerciements,
Pitchoonet
Pitchoonet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 18h36   #7
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 442
Points : 10 442
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Il faudrait voir la structure de façon un peu plus globale, déjà est-ce que la centaine de colonnes se justifie totalement dans la table de faits ?

C'est beaucoup cent colonnes, j'espère que vous n'avez pas construit une matrice creuse pour coller au modèle en étoile.

Votre table de faits est-elle construite avec une clef primaire clustered ou non-clustered ?
Dans ce cas-ci, vu que l'accès aux données ne se fait pas sur la clef primaire, j'opterais pour une non-clustered, au contraire de toutes vos tables de références.

Est-ce que vos colonnes de références sont toutes indexées ?
Est-ce que vos relations sont correctement définies par des clefs étrangères ?
Est-ce que vous avez essayé votre requête avec des index composites ?

Si la requête que vous avez présenté au départ est représentative de votre vraie requête, le distinct dans le count est inutile.
Pour le case à l'intérieur de celui-ci, je ne sais pas, ça dépend de vos données et de ce que vous essayez d'en extirper.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/05/2011, 19h02   #8
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
Citation:
le passage de 9 à 10 jointures avec des tables de référence : ma requête passe de 1mn30 à 8mn
Postez le plan d’exécution...

Sur le plan d’exécution estimé, le nombre de lignes qu'il estime traiter est'il cohérent avec le nombre réel de lignes?
J'ai eu le soucis sur une requête avec de multiples LEFT JOIN... il manquait une statistiques sur un couple de colonnes... je suis ainsi passé de 5mn... à 3secondes :-)
Un coups d'oeil de ce côté là ne fera pas de mal...
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 13h04   #9
Responsable SQL Server

 
Avatar de mikedavem
 
Homme David BARBARIN
Expert SQL Server
Inscription : août 2005
Messages : 3 723
Détails du profil
Informations personnelles :
Nom : Homme David BARBARIN
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Expert SQL Server
Secteur : Conseil

Informations forums :
Inscription : août 2005
Messages : 3 723
Points : 6 844
Points : 6 844
Citation:
J'ai eu le soucis sur une requête avec de multiples LEFT JOIN... il manquait une statistiques sur un couple de colonnes... je suis ainsi passé de 5mn... à 3secondes :-)
Un coups d'oeil de ce côté là ne fera pas de mal...
Ah tiens ca me rappelle qqch
mikedavem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 14h10   #10
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
Citation:
Ah tiens ca me rappelle qqch

A toi aussi

Une épidémie surement
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 14h47   #11
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 668
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

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

Informations forums :
Inscription : janvier 2005
Messages : 4 668
Points : 8 718
Points : 8 718
Effectivement, la Thaïlande étant également touchée ...
Et c'est probablement pas le seul pays

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 15h11   #12
Invité de passage
 
Femme
Développeur décisionnel
Inscription : mai 2011
Messages : 10
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Développeur décisionnel
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 10
Points : 0
Points : 0
Ce n'est pas moi qui ai construit le modèle et il est trop tard pour le modifier.
Je fais donc avec ce dont j'hérite...
Concernant les indexs de PK, ils sont en cluster. Je vais essayer de le passer en non cluster sur la table de fait.
A ce sujet, est-il possible de créer une contrainte de PK sans l'index sous SQL Server?
Pour l'histoire des statistiques, svp pouvez-vous m'indiquer comment les voir?
Pitchoonet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 15h18   #13
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
Citation:
Concernant les indexs de PK, ils sont en cluster. Je vais essayer de le passer en non cluster sur la table de fait.
?

Citation:
A ce sujet, est-il possible de créer une contrainte de PK sans l'index sous SQL Server?
Non mais en quoi l'index vous gène t'il?

Citation:
Pour l'histoire des statistiques, svp pouvez-vous m'indiquer comment les voir?
Code :
1
2
3
SELECT * 
FROM sys.stats 
WHERE object_id=OBJECT_ID(NOMDEVOTRETABLE)

Mais plus visuellement dans SSMS au niveau de votre table vous avez un node 'statistiques'
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 15h19   #14
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
Mais le mieu est vraiment de nous fournir le plan d'execution comme vous l'a expliqué elsuket
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 16h38   #15
Invité de passage
 
Femme
Développeur décisionnel
Inscription : mai 2011
Messages : 10
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Développeur décisionnel
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 10
Points : 0
Points : 0
Voici les plans d'exécutions.

Avec mes remerciements,
Pitchoonet
Fichiers attachés
Type de fichier : zip SqlPlans.zip (10,6 Ko, 7 affichages)
Pitchoonet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 16h51   #16
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
Citation:
Voici les plans d'exécutions.
Déjà les requètes ne sont pas équivalentes... j'en veux pour preuve le group by...

Il vous manque également des index... SQL SERVER (est'il gentil tout de même) vous en propose dailleurs...


commencez par harmoniser vos Requètes et creez l'index manquant (profitez en pour aliaser vos tables!!! c'est illisible)
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 17h04   #17
Invité de passage
 
Femme
Développeur décisionnel
Inscription : mai 2011
Messages : 10
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Développeur décisionnel
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 10
Points : 0
Points : 0
La proposition de SQL Server (il est gentil:-)) est de créer un index avec inclusion de toutes les colonnes de mon select...
C'est une solution trop spécifique pour être acceptable dans le contexte de mon projet...
Pitchoonet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 19h19   #18
Responsable SQL Server

 
Avatar de mikedavem
 
Homme David BARBARIN
Expert SQL Server
Inscription : août 2005
Messages : 3 723
Détails du profil
Informations personnelles :
Nom : Homme David BARBARIN
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Expert SQL Server
Secteur : Conseil

Informations forums :
Inscription : août 2005
Messages : 3 723
Points : 6 844
Points : 6 844
Effectivement créer un index avec l'ensemble des colonnes devient abérant. Cependant la plus grosse consommation de votre requête vient de la table TF_COMPTE.

Que pouvez vous nous dire sur la cardinalité de valeurs de la colonne TF_COMPTE.EDITEUR_TF1_FR_ID ?

Quelle est la proportion de valeurs <> 0 dans cette table ?

Code :
TF1BDDCiblage.Contact.TF_COMPTE.EDITEUR_TF1_FR_ID <> 0
Est ce que l'ajout d'un index non cluster sur cette colonne est envisageable ?

++
mikedavem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 19h34   #19
Invité de passage
 
Femme
Développeur décisionnel
Inscription : mai 2011
Messages : 10
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Développeur décisionnel
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mai 2011
Messages : 10
Points : 0
Points : 0
La colonne EDITEUR_TF1_FR_ID est de type bit.
Voici la répartition des lignes dans la table TF_COMPTE:
0 10207666
1 7295917

J'ai déjà créé un index non cluster sur cette colonne. C'est ma seule condition de clause WHERE et donc mon premier réflexe.
Mais le plan d'exécution ne l'utilise pas...
Toute proposition de création d'index est la bienvenue.
Svp, y a-t-il l'équivalent des indexs bitmap en SQL Server?

Avec mes remerciements,
Pitchoonet
Pitchoonet est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/05/2011, 20h34   #20
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 442
Points : 10 442
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
C'est normal que l'optimiseur choisisse de ne pas utiliser l'index, il n'est absolument pas discriminant.

Si ce critère revient dans beaucoup de vos requêtes vous gagneriez à partitionner votre table sur cette colonne.
__________________
Email : http://scr.im/waldar
Waldar 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 11h18.


 
 
 
 
Partenaires

Hébergement Web