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

Langage SQL Discussion :

Performance jointure sql


Sujet :

Langage SQL

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2008
    Messages : 144
    Points : 68
    Points
    68
    Par défaut Performance jointure sql
    Bonjour j'ai une requete sql généré en partie par SSRS( pas d'utilisation d'alias désolé)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT        REPLACE(LTRIM(REPLACE(INVENTORY.MATNR, 0, ' ')), ' ', 0) AS MATNR, INVENTORY.WERKS, INVENTORY.LGORT, INVENTORY.CHARG, INVENTORY.SOBKZ, REPLACE(LTRIM(REPLACE(INVENTORY.KUNNR, 0, 
                             ' ')), ' ', 0) AS KUNNR, REPLACE(LTRIM(REPLACE(INVENTORY.LIFNR, 0, ' ')), ' ', 0) AS LIFNR, INVENTORY.VBELN, INVENTORY.POSNR, INVENTORY.LABST, INVENTORY.UMLME, INVENTORY.INSME, 
                             INVENTORY.EINME, INVENTORY.SPEME, INVENTORY.RETME, INVENTORY.DLINL, INVENTORY.LGBPE, INVENTORY.KZILL, INVENTORY.KZILQ, INVENTORY.KZILE, INVENTORY.KZILS, INVENTORY.DISKZ, 
                             INVENTORY.[MBEW-VPRSV], INVENTORY.[MBEW-BKLAS], INVENTORY.[MBEW-LAEPR], INVENTORY.[MBEW-BWTTY], INVENTORY.PRICE, INVENTORY.[MBEW-BWTAR], INVENTORY.Total_Value, 
                             INVENTORY.GUID, INVENTORY.Stock_Price, INVENTORY.Stock_Value, INVENTORY.Sum, MATERIAL.FRdes, MATERIAL.ENdes, MATERIAL.DEdes, MATERIAL.ITdes, MATERIAL.ESdes, MATERIAL.PTdes, 
                             MATERIAL.NLdes, MATERIAL.MTART, MATERIAL.MATKL, Material_Detail.EKGRP, Material_Detail.DISPO
    FROM           INVENTORY  
                              LEFT OUTER JOIN
                             Material_Detail ON INVENTORY.MATNR = Material_Detail.MATNR AND INVENTORY.WERKS = Material_Detail.WERKS INNER JOIN
    						 Material ON MATERIAL.MATNR = INVENTORY.MATNR 
    WHERE      /*(INVENTORY.WERKS IN (@werks)) AND (ISNULL(INVENTORY.LGORT, 'NULL') IN (@lgort)) AND (REPLACE(LTRIM(REPLACE(INVENTORY.MATNR, 0, ' ')), ' ', 0) = @MATNR) AND (INVENTORY.DATE = @date1) AND 
                             (ISNULL(INVENTORY.SOBKZ, 'NULL') IN (@sobkz)) AND (ISNULL(INVENTORY.DLINL, '2000-01-01') < ISNULL(@date_inventaire, GETDATE())) OR
                             (INVENTORY.WERKS IN (@werks)) AND (ISNULL(INVENTORY.LGORT, 'NULL') IN (@lgort)) AND*/ (INVENTORY.DATE = '2016-06-27')/* AND (ISNULL(INVENTORY.SOBKZ, 'NULL') IN (@sobkz)) AND 
                             (ISNULL(INVENTORY.DLINL, '2000-01-01') < ISNULL(@date_inventaire, GETDATE())) AND (@MATNR IS NULL)*/
    Je devrais avoir 29450 ligne en gros que j'arrive à obtenir mais en seulement 6 minutes 30, si ma première jointure est en inner join cela prends 12 secondes pour 29000 lignes (normal que des lignes disparaissent, pas de soucis la dessus). Pourquoi une telle différence de temps , c'est comme si il prenait le where en compte différement en inner join et en left outer join.
    Quelqu'un pourrait-il m'aider ou au moins m'expliquer cette différence?

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    La jointure est étrange, est-il normal qu'il n'y ait pas de lien entre Material et Material_Detail ?

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2008
    Messages : 144
    Points : 68
    Points
    68
    Par défaut
    Je n'ai pas besoin de ce lien effectivement,
    qu'y a t'il d'étrange j'ai une table principale et je vais chercher des informations dans 2 autre table?

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par oupepasa Voir le message
    qu'y a t'il d'étrange
    Sémantiquement parlant, il est étrange qu'il n'y ait pas de lien entre MATERIAL et MATERIAL_DETAIL. Le choix du nom des tables ne semble donc pas très pertinent.
    Citation Envoyé par oupepasa Voir le message
    j'ai une table principale et je vais chercher des informations dans 2 autre table?
    En fonction de la cardinalité des relations entre INVENTORY et MATERIAL et entre INVENTORY et MATERIAL_DETAIL, ça peut démultiplier les lignes :
    http://www.developpez.net/forums/d12...e/#post6958167

  5. #5
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    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 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Que se passe-t-il si vous mettez la jointure externe après la jointure interne ? (j'ai pour habitude de toujours renvoyer à la fin les jointures externes, me disant que ça permet au SGBD de commencer par la partie "facile", même si je doute un peu que ça change quoi que ce soit...)

    Les clés étrangères sont-elles matérialisées ?

    Si possible, créer les relations suivantes :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    alter table inventory add foreign key (matnr) references material (matnr);
    alter table Material_Detail add foreign key (matnr, werks) references inventory (matnr, werks);

    PS : Accessoirement, j'ai l'impression que votre table de départ est "material" et non "inventory".
    PS² : J'ai cependant un léger doute quant à la seconde contrainte... werks ne serait-il pas nullable dans la table inventory par hasard ?

    Que donne donc la clause FROM suivante ?

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    FROM Material 
    inner join INVENTORY on INVENTORY.MATNR = MATERIAL.MATNR
    LEFT OUTER JOIN Material_Detail ON Material_Detail.MATNR = INVENTORY.MATNR AND Material_Detail.WERKS = INVENTORY.WERKS

  6. #6
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    PS : Accessoirement, j'ai l'impression que votre table de départ est "material" et non "inventory".
    Ah oui, c'est pas faux.

  7. #7
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Dans la requete que vous avez postée, tous les prédicats sauf un sont en commentaire...
    Est-ce que vous parlez bien de la requete avec ces commentaires, ou en prenant en compte les prédicats commentés ? car certains (pour ne pas dire tous) sont très mal exprimés.

    Si vous parlez de la requete avec uniquement le filtre sur la date, il serait intéressant de comparer les plan d’exécution, mais il doit manquer des statistiques (ou elles sont obsolètes) pour arriver à de telles différences.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2008
    Messages : 144
    Points : 68
    Points
    68
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    Sémantiquement parlant, il est étrange qu'il n'y ait pas de lien entre MATERIAL et MATERIAL_DETAIL. Le choix du nom des tables ne semble donc pas très pertinent.
    il y a un lien , mais cela rajoute une jointure gauche pas sur que cela soit efficace

    Les clés étrangères sont-elles matérialisées ?
    Non mais les clés primaires non plus, ma table est plus construite comme un datawarehouse, ce qui pourrait expliquer ces contre performances effectivement


    PS : Accessoirement, j'ai l'impression que votre table de départ est "material" et non "inventory".
    PS² : J'ai cependant un léger doute quant à la seconde contrainte... werks ne serait-il pas nullable dans la table inventory par hasard ?

    Que donne donc la clause FROM suivante ?
    ps : a quoi voyez vous cela?
    ps1 : werks ne peut pas etre null
    La clause donne le meme résultat et à vrai dire c'était effectivement celle que ssrs m'a construite à la base


    Bonjour,

    Dans la requete que vous avez postée, tous les prédicats sauf un sont en commentaire...
    Est-ce que vous parlez bien de la requete avec ces commentaires, ou en prenant en compte les prédicats commentés ? car certains (pour ne pas dire tous) sont très mal exprimés.

    Si vous parlez de la requete avec uniquement le filtre sur la date, il serait intéressant de comparer les plan d’exécution, mais il doit manquer des statistiques (ou elles sont obsolètes) pour arriver à de telles différences.
    c'est bien la requete avec seulement ce filtre dont je parle



    Je pense que ma solution (de facilité) sera d'ajouter ces champs au moments de la création de la table si je ne trouve rien de mieux

  9. #9
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par oupepasa
    Les clés étrangères sont-elles matérialisées ?
    Non mais les clés primaires non plus, ma table est plus construite comme un datawarehouse, ce qui pourrait expliquer ces contre performances effectivement
    oui, il n'y a pas a chercher beaucoup plus loin

    si les clef primaires ne sont pas déclarées, alors vous n'avez certainement pas d'index sur ces tables.
    Par ailleurs, le moteur ne peut pas "savoir" que chaque ligne dans Material_Detail aura forcément une correspondance dans la table inventory; Il va donc s'appuyer sur des statistiques globales, ce qui peut tout à fait expliquer la différence de comportement entre les deux types de jointure.

  10. #10
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par oupepasa
    Je pense que ma solution (de facilité) sera d'ajouter ces champs au moments de la création de la table
    A terme, cela risque d'empirer la situation globale et de vous mener a d'autres problèmes.

    1/ Déclarez les clefs primaires et étrangères.
    2/ indexez les clefs étrangères (ce sera fait automatiquement pour les clef primaires)
    3/ créez un index sur inventory.DATE

    tout devrait aller beaucoup mieux (il y aurait surement même moyen de faire mieux, mais ce sera déjà un bon début.)

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2008
    Messages : 144
    Points : 68
    Points
    68
    Par défaut
    le probleme c'est que je n'ai pas forcement une clé unique par table

    en plus c'est une table qui est rechargé integralement tous les matins donc ca pose peu de probleme

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

Discussions similaires

  1. un client performant avec SQL Server
    Par hani dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 16/06/2006, 10h56
  2. Performance requete SQL
    Par billout9 dans le forum Oracle
    Réponses: 4
    Dernier message: 28/11/2005, 21h13
  3. performance de sql server
    Par samsih dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 24/11/2005, 16h46
  4. Réponses: 4
    Dernier message: 11/10/2005, 10h17
  5. Performance Jointure
    Par jflebegue dans le forum Décisions SGBD
    Réponses: 4
    Dernier message: 01/12/2004, 22h41

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