Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server
MS SQL-Server Forum Microsoft SQL-Server. Avant de poster -> FAQ SQL-Server, Tutoriels SQL-Server
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 06/02/2012, 10h26   #1
Expert Confirmé Sénior
 
Avatar de Pol63
 
Homme Sébastien
Développeur informatique
Inscription : avril 2007
Messages : 9 207
Détails du profil
Informations personnelles :
Nom : Homme Sébastien
Âge : 30
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : Industrie

Informations forums :
Inscription : avril 2007
Messages : 9 207
Points : 13 442
Points : 13 442
Par défaut ORDER BY qui plombe une requête de 4k lignes

bonjour

j'ai une requete qui retourne 4200 lignes
celle ci mettant 2'30" à s'exécuter j'ai regardé le plan d'exécution, et il en retourne que l'order by prend 85% du temps
en effet si je retire l'order by la requête s'exécute en moins d'une seconde

cette requête est devenue longue suite à l'ajout de cette colonne :
Code :
1
2
3
4
5
COALESCE(  MontantForce,
             SUM(DevisVersionCoeffChapitres.TotalBrut) + MargeForcee,  
             SUM(DevisVersionCoeffChapitres.TotalBrut) / (1 - PctMargeForcee / 100), 
             SUM(DevisVersionCoeffChapitres.TotalNet)
           ) AS PrixVente
donc avec cette colonne et l'order by => + de 2 minutes
avec la colonne sans l'order by OU sans la colonne et avec l'order by => moins d'une seconde


pourquoi ce comportement ? où sql server se fait avoir ? comment améliorer le temps ?
l'order by et bien à la fin du plan d'exécution, donc je vois pas quoi ca pourrait le perturber ...

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FROM DevisEntete 
        INNER JOIN Tiers Site   ON DevisEntete.IdSite = Site.IdTiers
        INNER JOIN Tiers ChargeAffaire   ON DevisEntete.ChargeAffaire = ChargeAffaire.IdTiers
        INNER JOIN DevisCommerce   ON DevisEntete.IdCommerce = DevisCommerce.IdDevisCommerce
        INNER JOIN DevisSecteur   ON DevisEntete.IdSecteur = DevisSecteur.IdDevisSecteur
        INNER JOIN DevisStatut   ON DevisEntete.IdStatut = DevisStatut.IdDevisStatut
        INNER JOIN DevisActivite   ON DevisEntete.IdActivite = DevisActivite.IdDevisActivite
        LEFT JOIN Tiers Client   ON Site.TiersLie = Client.IdTiers
        LEFT JOIN Tiers MaitreDOeuvre   ON DevisEntete.MaitreDOeuvre = MaitreDOeuvre.IdTiers
        LEFT JOIN DevisVersion   ON DevisEntete.IdDevis = DevisVersion.IdDevis AND DevisVersion.IsActive = 1
        LEFT JOIN DevisVersionCoeffChapitres   ON DevisVersionCoeffChapitres.IdDevisVersion = DevisVersion.IdDevisVersion
 
 
WHERE (DevisEntete.IdStatut <> 7 OR @suppr = 1)
GROUP BY DevisEntete.IdDevis, DevisEntete.NumDevis, DevisEntete.IdSite, Client.IdTiers, Client.Designation, Site.IdTiers, Site.Designation, DevisEntete.Description, DevisEntete.ChargeAffaire, ChargeAffaire.IdTiers, ChargeAffaire.Designation + ' ' + ChargeAffaire.Code, DevisEntete.DateRealisationTheo, DevisStatut.IdDevisStatut, DevisStatut.LibStatut, DevisActivite.IdDevisActivite, DevisActivite.CodeActivite, DevisActivite.LibActivite, DevisCommerce.IdDevisCommerce, DevisCommerce.LibCommerce, DevisSecteur.IdDevisSecteur, DevisSecteur.CodeSecteur, DevisSecteur.LibSecteur, DevisEntete.MaitreDOeuvre, MaitreDOeuvre.IdTiers, MaitreDOeuvre.Designation,  DevisEntete.IdCommerce, DevisEntete.IdSecteur, DevisEntete.IdActivite, DevisEntete.IdStatut,
DevisStatut.Couleur, DevisEntete.Commentaire, MontantForce, MargeForcee, PctMargeForcee
merci
__________________
si vous ne comprenez pas ce que je dis, demandez à google
Pol63 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/02/2012, 12h21   #2
Membre Expert
 
Homme Etienne ZINZINDOHOUE
Ingénieur développement
Inscription : mars 2010
Messages : 1 139
Détails du profil
Informations personnelles :
Nom : Homme Etienne ZINZINDOHOUE
Localisation : France, Nord (Nord Pas de Calais)

Informations professionnelles :
Activité : Ingénieur développement
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : mars 2010
Messages : 1 139
Points : 2 470
Points : 2 470
Envoyer un message via Yahoo à zinzineti
Après l'ajout de la nouvelle colonne, avez-vous mis à jour les statistiques (UPDATE STATISTICS ....) ?
Si non, réessayer après la mise à jour des statistiques.
SQL SERVER utilises les statistiques pour décider des algorithmes à utiliser pour générer le plan d'exécution.

Donc si vous modifier le modèle de données (création de nouvelles colonnes, création d'index, .....) alors il faut mettre à jour les statistiques afin d'aider le moteur SQL SERVER à une prise de décision intelligente.
__________________
Etienne ZINZINDOHOUE
Billets-Articles
zinzineti est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/02/2012, 14h00   #3
Expert Confirmé Sénior
 
Avatar de Pol63
 
Homme Sébastien
Développeur informatique
Inscription : avril 2007
Messages : 9 207
Détails du profil
Informations personnelles :
Nom : Homme Sébastien
Âge : 30
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : Industrie

Informations forums :
Inscription : avril 2007
Messages : 9 207
Points : 13 442
Points : 13 442
je me suis mal exprimé, l'ajout de colonne n'est pas sur la structure, mais sur la requête, avant la requête n'affichait pas cette colonne calculée, j'ai rajouté ce coalesce dans le select et j'ai vu le délai
au début j'ai pensé que c'était cette expression qui plombait le résultat, puis j'ai recherché sur le plan d'exécution pour voir que ce n'est pas le cas mais la combinaison de ce calcul + order by
__________________
si vous ne comprenez pas ce que je dis, demandez à google
Pol63 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/02/2012, 14h53   #4
Responsable SQL Server

 
Avatar de mikedavem
 
Homme David BARBARIN
Expert SQL Server
Inscription : août 2005
Messages : 3 726
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 726
Points : 6 851
Points : 6 851
Possibilité d'avoir les 2 plans d'exécution de requêtes et les statistiques d'exécutions via SET STATISTICS TIME ON et SET STATISTICS IO ON ?

++
mikedavem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/02/2012, 15h09   #5
Expert Confirmé Sénior
 
Avatar de Pol63
 
Homme Sébastien
Développeur informatique
Inscription : avril 2007
Messages : 9 207
Détails du profil
Informations personnelles :
Nom : Homme Sébastien
Âge : 30
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : Industrie

Informations forums :
Inscription : avril 2007
Messages : 9 207
Points : 13 442
Points : 13 442
sql server 2005 sp3 standard x64
Fichiers attachés
Type de fichier : zip plans et stats.zip (41,2 Ko, 4 affichages)
__________________
si vous ne comprenez pas ce que je dis, demandez à google
Pol63 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/02/2012, 15h23   #6
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 674
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 674
Points : 8 741
Points : 8 741
Bonjour,

Il semble que vous ayez un léger problème d'estimation de cardinalités dans les deux cas.
La requête prend du temps à cause du spool : 500.000+ IOs sur une table de travail, ça veut souvent dire qu'il manque un index pour aider la requête.

Quelle est la définition de la table DevisVersionCoeffChapitre, avec ses index ?

@++
__________________
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 10
Vieux 06/02/2012, 15h48   #7
Expert Confirmé Sénior
 
Avatar de Pol63
 
Homme Sébastien
Développeur informatique
Inscription : avril 2007
Messages : 9 207
Détails du profil
Informations personnelles :
Nom : Homme Sébastien
Âge : 30
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : Industrie

Informations forums :
Inscription : avril 2007
Messages : 9 207
Points : 13 442
Points : 13 442
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE [dbo].[DevisVersionCoeffChapitres](
    [IdDevisVersionCoeff] [bigint] IDENTITY(1,1) NOT NULL,
    [IdDevisVersion] [bigint] NOT NULL,
    [IdChapitre] [bigint] NOT NULL,
    [IdLigneBud] [bigint] NOT NULL,
    [TotalBrut] [decimal](19, 5) NOT NULL,
    [Coeff] [decimal](3, 2) NOT NULL,
    [TotalNet]  AS (case when [coeff]=(0) then NULL else [TotalBrut]/[Coeff] end) PERSISTED,
 CONSTRAINT [PK_DevisVersionCoeffChapitres] PRIMARY KEY CLUSTERED 
(
    [IdDevisVersionCoeff] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
2 indexes :
- IdLigneBud
- IdDevisVersion, IdLigneBud, IdChapitre


et j'ai refait un sp_updatestats 'RESAMPLE' pas longtemps avant de fournir les plans d'exécution ...

il me semble logique de mon point de vue que faire un order by ca se fait à la fin et que ca prend un court laps de temps en ram, donc je ne vois pas pourquoi sql server patinerait à faire autre chose quand je lui demande un order by ^^
__________________
si vous ne comprenez pas ce que je dis, demandez à google
Pol63 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/02/2012, 17h35   #8
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 674
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 674
Points : 8 741
Points : 8 741
La requête longue parallélise, pas la courte ...
Si quand la longue s'exécute vous avez un wait_time long avec le wait_type CX_PACKET, c'est que c'est la parallélisation qui pose problème.
Donc soit vos statistiques ne sont pas à jour (je ne sais plus pourquoi je n'utilise plus sp_updatestats maintenant ... j'utilise UPDATE STATISTICS), soit votre table est fragmentée
SQL Server est donc soit perdu dans son calcul d'équilibrage de la charge de travail des threads, ou attend qu'un thread ait terminé parce qu'il a mal estimé ou que la table est fragmentée.

Aussi, comme TotalBrut n'est pas indexée, et que vous faites un groupement dessus, cela n'aide pas. Donc SQL Server n'a pas d'autre choix que de faire cela dans une table temporaire dans TempDB, et c'est cela qui plombe vos performances.

@++
__________________
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 10
Vieux 06/02/2012, 17h47   #9
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 959
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 959
Points : 17 791
Points : 17 791
Exécutez la avec une OPTION(MAXDOP 1) pour voir...

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 10
Vieux 06/02/2012, 18h08   #10
Expert Confirmé Sénior
 
Avatar de Pol63
 
Homme Sébastien
Développeur informatique
Inscription : avril 2007
Messages : 9 207
Détails du profil
Informations personnelles :
Nom : Homme Sébastien
Âge : 30
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : Industrie

Informations forums :
Inscription : avril 2007
Messages : 9 207
Points : 13 442
Points : 13 442
la table DevisVersionCoeffChapitres est fragmentée à 0.9%
msdn disait il me semble que sp_updatestats appelle update statistics

le option maxdop a l'air bon, 10x de suite 2 secondes, on va faire avec

merci bien à tous
__________________
si vous ne comprenez pas ce que je dis, demandez à google
Pol63 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/02/2012, 18h13   #11
Expert Confirmé Sénior
 
Avatar de Pol63
 
Homme Sébastien
Développeur informatique
Inscription : avril 2007
Messages : 9 207
Détails du profil
Informations personnelles :
Nom : Homme Sébastien
Âge : 30
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : Industrie

Informations forums :
Inscription : avril 2007
Messages : 9 207
Points : 13 442
Points : 13 442
re,

en cherchant des infos sur le maxdop j'ai trouvé des gens qui faisaient un force order
je viens de tester, le force order sans le maxdop est encore mieux, je suis en dessous d'une seconde
__________________
si vous ne comprenez pas ce que je dis, demandez à google
Pol63 est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h27.


 
 
 
 
Partenaires

Hébergement Web