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 :

Temps d’exécution avec jointure


Sujet :

Développement SQL Server

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2011
    Messages : 23
    Points : 29
    Points
    29
    Par défaut Temps d’exécution avec jointure
    Bonjour,
    alors voici mon problème, j'ai une requête qui fait un select sur 2 T1 et T2 tables avec une jointure entre T1 et T2
    lorsque je fait un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    select T1.a, T1.b, T2.* 
    From T1 inner join T2 on T1.id2 = T2.id
    ....

    La requête s’exécute en 3 secondes.
    Si je remplace T2.* par T2.A
    la requête mais 9 minutes !!!!

    Si je regarde le plan d’exécution dans le second cas j'ai une tache sort qui est
    faite sur le résultat de la jointure T2 qui prends 45% du temps .

    Je comprends pas pourquoi ce sort apparaît, et je ne sais pas non plus comment faire pour le supprimer.

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2011
    Messages : 23
    Points : 29
    Points
    29
    Par défaut
    Bon en fait ca ne le fait que si certaine colonnes ne sont pas dans la selection (se qui explique qu avec select * ca fonctionne)
    par contre je ne comprends toujours pas pourquoi le fait de selectionner ou non une colonne à un impacte aussi important sur le temps d'execution d'une requête.

    J'ai une piste que je vais creusé demain qui s'oriente vers les statistique de SQL mais je n'y connais rien a ce sujet.

    Est-ce que ca vous parait être une piste intéressante?

  3. #3
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Peux-tu poster la "vraie" requête complète.

    Parfois le SGBD fait des "optimisations" qui peuvent être malencontreuses, et cela dépends de l'ensemble de la "vraie" requête.

    Un exemple probant d'optimisation à la noix, c'est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    select champ1
    from (
      select champ1, champ2
      from matable
      where champ2 != ' '
    ) t
    where cast(champ2 as datetime) < getdate()
    Avec SQL Server, je sais pas ce que ça donne, mais avec Oracle, le cast va planter sur les valeurs ' ' de champ2 malgré le filtre dans la sous-requête : il a décidé que c'était plus rapide de filtrer la date avant que de vérifier sa valeur, va comprendre Charles...

    Je doute pour ton problème précis que les statistiques soient la cause première de ce problème.
    On ne jouit bien que de ce qu’on partage.

  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 : 42
    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
    Points : 3 173
    Points
    3 173
    Par défaut
    Avec SQL Server, je sais pas ce que ça donne, mais avec Oracle, le cast va planter sur les valeurs ' ' de champ2 malgré le filtre dans la sous-requête : il a décidé que c'était plus rapide de filtrer la date avant que de vérifier sa valeur, va comprendre Charles...
    Ca va planter aussi ce qui est normal...

    La solution dans ton cas est d'utiliser un index filtré...
    Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
    MCTS Database Development
    MCTS Database Administration

  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 : 42
    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
    Points : 3 173
    Points
    3 173
    Par défaut
    La requête s’exécute en 3 secondes.
    Si je remplace T2.* par T2.A
    la requête mais 9 minutes !!!!
    Postes ton plan d'execution...
    Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
    MCTS Database Development
    MCTS Database Administration

  6. #6
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par iberserk Voir le message
    Ca va planter aussi ce qui est normal...

    La solution dans ton cas est d'utiliser un index filtré...
    Dans mon cas, vu que j'avais besoin seulement de la liste des champ1 (donc un distinct ne me gênait pas) je m'en suis tiré de la sorte :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT champ1
    FROM (
      SELECT champ1, champ2
      FROM matable
      WHERE champ2 != ' '
    ) t
    group by champ1
    having min(cast(champ2 AS datetime)) < getdate()

    Ce qui m'évitait de toucher aux index, puisque je n'ai pas droit d'y toucher

    La clause HAVING, sauveuse du monde quand on veut absolument faire un filtre "après" l'exécution de la requête
    On ne jouit bien que de ce qu’on partage.

  7. #7
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Je vous ai donné une meilleure solution depuis.

    On ne peut pas reprocher à un SGBD de réécrire des requêtes quand même, c'est son rôle de choisir comment il sélectionne ses données.

    Si les statistiques lui indique que c'est plus rapide de tout lire et d'appliquer des conversions ensuite, je ne vois pas pourquoi il procéderait autrement.

    Il ne peut pas deviner à votre place que dans un certain cas telle donnée est une date et dans un autre cas une chaîne de caractères.

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2011
    Messages : 23
    Points : 29
    Points
    29
    Par défaut
    Désolé,
    mais je n'arrive plus a reproduire le problème, j'ai travaillé dessus en attendant d'avoir une réponse sur le forum et maintenant la présence ou non de T2.* n'a plus d'impact.
    Ce qui est sur c'est qu'hier le plan d’exécution n'était pas le même dans les deux cas. sans le T2.* il y avait un sort qui prenait 68% du temps, sort qui n'existait pas avec T2.*

    Il me reste néanmoins d'autres problèmes sur le temps que prend cette requête que voici:
    Ce qui me pose probleme ce sont les éléments de la clause where et l'appel de la fonction FunctGetIdBag qui me retourne la valeur max de o.id_bagage pour un o.id_bsm donné:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    declare @id_emport as integer;
    declare @id_vol as integer;
    declare @dateDeb datetime
    declare @dateFin datetime
    declare @codeIata varchar(10)
    declare @listeCie varchar(50)
    declare @listeLigne varchar(50)
    declare @listeCre varchar(50)
    declare @classeBag as bit
    declare @listeStatutSurete varchar(50)
    declare @listeStatutTache varchar(50)
    declare @listeTroncon varchar(50)
     
    --Via l'Id emport
    set @id_emport = null
     
    --Via l'Id vol
    set @id_vol = 281646 
     
    --Via le filtre de recherche
    set @dateDeb = null
    set @dateFin = null
    set @listeCie = null --'TG'
    set @listeLigne = null
    set @listeCre = null
    set @classeBag = null
    set @listeStatutSurete = null
    set @listeStatutTache = null
    set @listeTroncon = null
     
    USE [CDG1]
     
    select o.ordre_apparition, b.id_vol, b.id_bsm, tgb.id_emport, 
    -- DETAILS
    	'CodeIata' = b.CODE_IATA, 'Compagnie' = b.CIEE, 'Ligne' = b.Lige, 'JourExploitation' = b.Jexe, 'Creation' = b.DAT_CRE, 
    	master.dbo.OrigineBsm(b.CRE) as OrigineCreation, 'Recolle' = b.RECOL, master.dbo.SourceIndicator(b.typ) as SourceIndicator, 
    	'Doublon' = b.DUP, 'Embarquable' = b.EMB, 'ReRoutage' = b.CHGVOL, 	'Suppression' = b.SUP,
    	master.dbo.getParticularites(b.id_bsm) as 'Particularites',
    --ITINERIARE
    	'AeroportContinuation' = b.ITI, 'Continuation' = b.CNT, 'AeroportDestination' = b.AER_DES,
    --PASSAGERS
    	'Noms' = b.NOM_PASSAGER, master.dbo.PassagerStatus(b.STA) as PassagerStatus, 'Prioritaire' = b.CLA,
    --SURETE
    		'ResultatControle' = b.ISUR, master.dbo.BagageStatus(b.SSUR) as BagageStatus, master.dbo.SecurityMethod(B.TSUR) as SecurityMethod, 
    	'Signature' = B.GSUR, 'ForcageN3' = b.SSURC,
    	st.nom_res as Localisation, 
    	master.dbo.CodeTrace(48, o.STATUT_SURETE_EJECTION) as StatutSurete, 'Commentaire' = b.CSUR,
    	tgb.CAR_CLASS as CarClass, tgb.Statut_temporel as SatatuTemporel
    FROM BSM b
    --	left outer join OCCURENCE_BAGAGE o on o.id_Bagage = master.dbo.FunctGetIdBag(b.id_bsm)
    	left outer join OCCURENCE_BAGAGE o on o.id_bsm = b.id_bsm
    	left outer join BSM_VOL_APPORT bva on bva.ID_BSM = b.ID_BSM
     
    	left outer join tac_grp_bags tgb on tgb.id_tache = o.id_tache_1 
    	left outer join Sortie_tri st on st.id_res = tgb.id_res
     
    	--left outer join TRACE_BAGAGE t on type = 80 and o.ID_BAGAGE = t.ID_BAGAGE and statut = 0 -- Trace d'éjection bagage
    WHERE (not (SUP=1 and RECOL=0)) 
    and 
    (
    	(@id_emport is not null and  b.Id_BSM in 
    		(	
    			select  bsm.id_bsm from bsm where bsm.id_vol in 
    			(
    				select id_vol from vol_depart where vol_depart.id_emport = @id_emport
    			)
    		)
    	)
    	or 
    	(@id_emport is null and @id_vol is not null and  b.Id_BSM in (select  bsm.id_bsm from bsm where bsm.id_vol = @id_vol))
    	or 
    	(@id_emport is null and @id_vol is null and
    			((@listeCie is not null and charindex(','+ltrim(rtrim(b.CIEE))+',', ','+@listeCie+',')>0) 
    			or @listeCie is null)
    			and 
    				((@listeCre is not null and charindex(','+b.cre+',', ','+@listeCre+',')>0) 
    				or @listeCre is null)
    			and
    				((@listeLigne is not null and charindex(','+ltrim(rtrim(b.LIGE))+',', ','+@listeLigne+',')>0) 
    				or @listeLigne is null)
    			and 
    				((@codeIata is not null and b.code_Iata like ('%'+@codeIata+'%')) 
    				or @codeIata is null)
    			and
    				((@classeBag is not null and b.CLA = @classeBag) 
    				or @classeBag is null)
    			and 
    				((@listeStatutSurete is not null and charindex(','+ltrim(rtrim(master.dbo.CodeTrace(48, o.STATUT_SURETE_EJECTION)))+',', ','+@listeStatutSurete+',')>0) 
    				or @listeStatutSurete is null)
    			and 
    				((@listeStatutTache is not null and charindex(','+ltrim(rtrim(tgb.Statut_temporel))+',', ','+@listeStatutTache+',')>0) 
    				or @listeStatutTache is null)
    			and 
    				((@listeTroncon is not null and charindex(','+ltrim(rtrim(st.nom_res))+',', ','+@listeTroncon+',')>0) 
    				or @listeTroncon is null)
    	)
    )
    order by o.id_bsm


    Merci

  9. #9
    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 : 42
    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
    Points : 3 173
    Points
    3 173
    Par défaut
    Le plan d’exécution et le temps d’exécution peuvent largement dépendre à tout moment de la charge de votre serveur...
    Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
    MCTS Database Development
    MCTS Database Administration

  10. #10
    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
    Citation Envoyé par StringBuilder
    La clause HAVING, sauveuse du monde quand on veut absolument faire un filtre "après" l'exécution de la requête
    C'est plutôt le seul moyen de filtrer un agrégat ...

    Citation Envoyé par StringBuilder
    Ce qui m'évitait de toucher aux index, puisque je n'ai pas droit d'y toucher
    Dans ce cas vous pouvez probablement en suggérer et les discuter

    @++

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2011
    Messages : 23
    Points : 29
    Points
    29
    Par défaut
    Le plan d’exécution et le temps d’exécution peuvent largement dépendre à tout moment de la charge de votre serveur...
    Je pensais que le plan d’exécution était lié uniquement aux contraintes et aux statistiques.
    Cela explique peut-être effet que j'ai constatés.

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 01/07/2015, 11h13
  2. Temps de reponse sur Select avec Jointure
    Par Guigsounet dans le forum SQL
    Réponses: 15
    Dernier message: 30/07/2010, 10h29
  3. Mise à jour de table impossible après requête avec jointure
    Par sto dans le forum Bases de données
    Réponses: 5
    Dernier message: 17/03/2004, 13h24
  4. Script avec JOINTURE et CASE
    Par Labienus dans le forum Langage SQL
    Réponses: 6
    Dernier message: 27/02/2004, 09h40
  5. problème de requête avec jointures
    Par tinhat dans le forum Requêtes
    Réponses: 7
    Dernier message: 11/08/2003, 10h33

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