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 :

Plan d'exécution d'un requête


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    IED décisionnel
    Inscrit en
    Mai 2011
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : IED décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 37
    Par défaut Plan d'exécution d'un requête
    Bonjour,

    lors d' un traitement sql j'ai deux requêtes de contrôle qui vont marquer un champ d'une table à ok pour ou à CI, les lignes dont ce champ est à Ok vont être insérées dans une autre table puis historiser dans dans un table d'histo.

    ce contrôle est fait par deux requête update IDENTIQUE la première avec des jointures vers 6 tables environs 2 millions de lignes chacunes. la deuxième vers une seul table avec 500000 lignes

    Mon problème est le suivant le deuxième update prend 50% du temps du traitement en regardant le plan d'exécution de cette requête il y un trie qui prend 86% du temps de la requête

    voici la requête en question:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    update s set SAS_STATUT=case
      when 1=0 then ''
      when SAS_STATUT = 'CI' then 'CI'
      when rg04.ID_PERS_SRC is null then 'CI'-- CG1 (une ligne par CI)
      else 'OK' end,SAS_ERREUR=substring(isnull(SAS_ERREUR,'')
      +case when rg04.ID_PERS_SRC is null then '[erreur de CI sur DWH_PERS]"'+isnull(convert(varchar,s.ID_PERS_SRC),'')+'" ;' else '' end -- CG1 (une ligne par CI)
     
      ,1,8000) from [dbo].SAS_SHIPPING_LINE s inner join #TMP_SHIPPING_LINE t on s.SAS_ID=t.SAS_ID
      left join [dbo].DWH_PERS rg04  on rg04.ID_PERS_SRC = s.ID_PERS_SRC and rg04.CD_BRAND=s.CD_BRAND and rg04.CD_COUNTRY=s.CD_COUNTRY -- CG1 (une ligne par CG)
      where t.RANG=@compteur and (s.SAS_STATUT is null or s.SAS_STATUT <> 'KO')
    Pourquoi fait il un trie aussi consommateur
    pourquoi le premier update identique et plus "lourd" (6 jointure vers des tables plus importantes) ne prend que 2 % du temps du traitement

  2. #2
    Expert confirmé
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Par défaut
    Est ce que votre première requête contient des tables temporaires ?
    Je vois que la deuxième en contient une ?

    On pourrait avoir les 2 requêtes et les plans d'exécutions ?

    ++

  3. #3
    Membre averti
    Homme Profil pro
    IED décisionnel
    Inscrit en
    Mai 2011
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : IED décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 37
    Par défaut
    Voici la première requête ainsi que les sqlplan en pj
    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
     
    update s set SAS_STATUT=case
      when 1=0 then ''
      when ri21.TYP_SHIP is null then 'CI'-- CI1 (une ligne par CI)
      when ri18.CD_CANCEL is null  and s.CD_CANCEL is not null then 'CI'-- CI2 (une ligne par CI)
      when rg08.ID_ORD_LINE_SRC is null then 'CI'-- CG2 (une ligne par CI)
      when rg07.ID_PACK_SRC is null then 'CI'-- CG3 (une ligne par CI)
      when rg09.ID_PRD_SRC is null then 'CI'-- CG4(une ligne par CI)
     
     
      else 'OK' end,SAS_ERREUR=substring(''
      +case when ri21.TYP_SHIP is null then '[erreur de CI sur DWH_REF_TYPE_SHIP_LINE]"'+isnull(convert(varchar,s.TYP_SHIP),'')+'" ;' else '' end -- CI1 (une ligne par CI)
      +case when ri18.CD_CANCEL is null and s.CD_CANCEL is not null  then '[erreur de CI sur DWH_REF_CANCEL_CODE]"'+isnull(convert(varchar,s.CD_CANCEL),'')+'" ;' else '' end -- CI2 (une ligne par CI)  
      +case when rg08.ID_ORD_LINE_SRC is null then '[erreur de CI sur DWH_ORDER_LINE]"'+isnull(convert(varchar,s.ID_ORD_LINE_SRC),'')+'" ;' else '' end -- CG2 (une ligne par CI)
      +case when rg07.ID_PACK_SRC is null then '[erreur de CI sur DWH_PACKAGE]"'+isnull(convert(varchar,s.ID_PACK_SRC),'')+'" ;' else '' end -- CG3 (une ligne par CI)
      +case when rg09.ID_PRD_SRC is null then '[erreur de CI sur DWH_PRODUCT]"'+isnull(convert(varchar,s.ID_PRD_SRC),'')+'" ;' else '' end -- CG4 (une ligne par CI)
      ,1,8000) from [dbo].SAS_SHIPPING_LINE s inner join #TMP_SHIPPING_LINE t on s.SAS_ID=t.SAS_ID
      left join [dbo].DWH_REF_TYPE_SHIP_LINE ri21 on ri21.TYP_SHIP=s.TYP_SHIP -- CI1 (une ligne par CI)
    												and ri21.CD_BRAND=s.CD_BRAND
    												and ri21.CD_COUNTRY=s.CD_COUNTRY
    												and ri21.CD_BUSLINE=s.CD_BUSLINE
      left join [dbo].DWH_REF_CANCEL_CODE ri18 on ri18.CD_CANCEL=s.CD_CANCEL -- CI2 (une ligne par CI)
    												and ri18.CD_BRAND=s.CD_BRAND
    												and ri18.CD_COUNTRY=s.CD_COUNTRY
    												and ri18.CD_BUSLINE=s.CD_BUSLINE
     
     
     
      left  join [dbo].DWH_ORDER_LINE rg08 on rg08.ID_ORD_LINE_SRC = s.ID_ORD_LINE_SRC and rg08.CD_BRAND=s.CD_BRAND and rg08.CD_COUNTRY=s.CD_COUNTRY and rg08.CD_BUSLINE=s.CD_BUSLINE -- CG2 (une ligne par CG)
      left  join [dbo].DWH_PACKAGE rg07 on rg07.ID_PACK_SRC = s.ID_PACK_SRC and rg07.CD_BRAND=s.CD_BRAND and rg07.CD_COUNTRY=s.CD_COUNTRY  and rg07.CD_BUSLINE=s.CD_BUSLINE-- CG3 (une ligne par CG)
     left  join [dbo].DWH_PRODUCT rg09 on rg09.ID_PRD_SRC = s.ID_PRD_SRC and rg09.CD_BRAND=s.CD_BRAND and rg09.CD_COUNTRY=s.CD_COUNTRY  and rg09.CD_BUSLINE=s.CD_BUSLINE-- CG4 (une ligne par CG)
      where t.RANG=@compteur and (s.SAS_STATUT is null or s.SAS_STATUT <> 'KO')
    Fichiers attachés Fichiers attachés

  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
    Bonne question de mikedavem, si la première n'en contient pas cherchez de ce côté là en priorité...

    Au passage ce que vous faites semble extrêmement coûteux et est le résultat d'une modélisation bancale ce qui entraîne des surcoûts comme l'extraction des chaines dans le case (substring etc.).

  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
    A nos message se sont croisés....

  6. #6
    Membre averti
    Homme Profil pro
    IED décisionnel
    Inscrit en
    Mai 2011
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : IED décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 37
    Par défaut
    y a t il un moyen de savoir se qui cause le trie (comme sous oracle) ou de forcer un plan d'exécution?

  7. #7
    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
    y a t il un moyen de savoir se qui cause le trie (comme sous oracle) ou de forcer un plan d'exécution?
    Si SQL SERVER s'efforce de faire un tri de l'entrée c'est qu'il a estimé que c'était la façon la plus rapide ensuite de traiter les informations...

    Il manque de toute evidence un index très important sur la table temporaire (comme il vous le dit dailleurs...).

    L'ajout d'un index peut très bien supprimer ce tri si SQL SERVER se retrouve avec une entrée triée comme il faut suite à l'utilisation de ce dernier.

    Essayez en créant cet index mais surtout posez vous la bonne question: pourquoi utilisez vous une table temporaire?

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

Discussions similaires

  1. Comment fige t-on le plan d'exécution d'une requête
    Par alexisongagna dans le forum Administration
    Réponses: 4
    Dernier message: 02/01/2013, 17h13
  2. Affichage du plan d'exécution d'une requête
    Par orafrance dans le forum Contribuez
    Réponses: 1
    Dernier message: 30/12/2011, 16h01
  3. Forcer le choix du plan d'exécution d'une requête
    Par hmechbal dans le forum Oracle
    Réponses: 5
    Dernier message: 20/01/2011, 23h28
  4. Réponses: 4
    Dernier message: 06/06/2008, 19h22
  5. [EXPLAIN PLAN] Exécution de la requête
    Par tux2005 dans le forum Oracle
    Réponses: 3
    Dernier message: 02/10/2007, 17h29

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