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

SQL Firebird Discussion :

Exécution tres Long d'une requête de Selection


Sujet :

SQL Firebird

  1. #1
    Membre actif Avatar de touhami
    Inscrit en
    Avril 2002
    Messages
    327
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 327
    Points : 264
    Points
    264
    Par défaut Exécution tres Long d'une requête de Selection
    Bonjour a tous,
    Je possède deux Tables
    Une table maître Des Ventes
    Structure de la Table Maitre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      NumeroBon  Integer Primary Key
        DateBon Date
        Code_Client Varchar(6)
    Et la table détail des ventes

    Structure de la Table Detail
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        NumeroBon  Integer 
        Code_Produit Varchar(10)
        Qte_Vendu Numeric(15,2)
        Pu_Vente Numeric(15,2)
        Benifice Numeric(15,2)  
    La clé primaire est (NumeroBon + CodeProduit)
    Nombre d'enregistrement de la Table Maitre : 12308
    Nombre d'enregistrement de la Table Detail : 91122


    J'ai Bien Ajouter un index secondaire a ma Table Detail sur le champ Benifice

    Mon but est d’avoir le benifice total dans la période allant du 01/01/2000 et 01/01/2006

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT  Sum(d1.Benifice)
    FROM Detail  D1 ,  Maitre d
    WHERE
       (D1.NumeroBon = D.NumeroBon)
        and (D.DateBon Between '01/01/2000' and '01/01/2006')
    L'exécution de la requête est Très Long et voici les Détails afficher dans ma Console

    Plan
    Statement: SELECT Sum(d1.Benifice)
    FROM Detail D1 , Maitre d
    WHERE
    (D1.NumeroBon = D.NumeroBon)
    and (D.DateBon Between '01/01/2000' and '01/01/2006')
    PLAN JOIN (D1 NATURAL,D INDEX (RDB$PRIMARY17,LADATEBON))

    Statistique

    Exécution 00:02:19.0109
    J'utilise Interbase 7.5 sous Windows XP.

  2. #2
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 925
    Points : 6 040
    Points
    6 040
    Par défaut
    As-tu un index sur DateBon ?

  3. #3
    Membre actif Avatar de touhami
    Inscrit en
    Avril 2002
    Messages
    327
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 327
    Points : 264
    Points
    264
    Par défaut
    Bonjour,
    et merci pour votre reponse,
    Oui il y a un index sur la dateBon,
    et c'est bien préciser dans le plan utiliser par Interbase

    PLAN JOIN (D1 NATURAL,D INDEX (RDB$PRIMARY17,LADATEBON))

  4. #4
    SLE
    SLE est déconnecté
    Membre éclairé Avatar de SLE
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Janvier 2004
    Messages : 604
    Points : 799
    Points
    799
    Par défaut
    Salut,


    Au lieu de faire ta jointure dans ta clause WHERE, essaie en faisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ... FROM Detail D1 join Maitre D on D1.NumeroBon = D.NumeroBon...
    Ca devrait améliorer les perfs.

    @+

  5. #5
    Membre confirmé Avatar de JustMe
    Inscrit en
    Juillet 2002
    Messages
    479
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 479
    Points : 594
    Points
    594
    Par défaut
    je de l'avis de SLE essais plutot la requete :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT  Sum(d1.Benifice)
    FROM Detail  D1 join  Maitre d
    on D1.NumeroBon = D.NumeroBon
    where (D.DateBon >= '01/01/2000') and (D.DateBon <= '01/01/2006')
    et tu nous informe du temps d'execution

  6. #6
    Membre actif Avatar de touhami
    Inscrit en
    Avril 2002
    Messages
    327
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 327
    Points : 264
    Points
    264
    Par défaut
    Bonjour,
    j'ai essayé l'avis de SLE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT  Sum(d1.Benifice) 
    FROM Detail  D1 join  Maitre d 
    on D1.NumeroBon = D.NumeroBon 
    where (D.DateBon >= '01/01/2000') and (D.DateBon <= '01/01/2006')
    mais seulement j'ai ganigner 2 secondes:
    00:02:17,
    meme j'ai essayé avec cette requete :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT  Sum(d1.Benifice) 
    FROM Detail  D1 join  Maitre d 
    on D1.NumeroBon = D.NumeroBon 
    where (D.DateBon >= '01/01/2000') and (D.DateBon <= '01/01/2006') 
    PLAN JOIN (D1 NATURAL,D INDEX (RDB$PRIMARY17,LADATEBON)
    mais pas de gros changement.
    Merci pour vos reponses.

  7. #7
    SLE
    SLE est déconnecté
    Membre éclairé Avatar de SLE
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Janvier 2004
    Messages : 604
    Points : 799
    Points
    799
    Par défaut
    Et en faisant ceci, qu'est-ce que ça donne comme temps d'execution ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT  Sum(Benifice) 
    FROM Detail
    where NumeroBon in (select NumeroBon from Maitre where DateBon between '01/01/2000' and '01/01/2006')

  8. #8
    Membre du Club
    Inscrit en
    Avril 2003
    Messages
    124
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 124
    Points : 56
    Points
    56
    Par défaut
    Au regard de ton plan d'exécution de la requête (créer automatiquement par IB), lB n'utilise pas comme premier critère un index. Contourne le problème toi-même en créant le PLAN. Il suffit d'ajouter PLAN (...) à la fin de la requête où tu commences ton plan par tes index primaires.
    Il faut savoir que IB est très performant sur les insert et les update, mais qu'en select il lui arrive de se planter complètement.

  9. #9
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Bonjour,

    Je viens de faire les tests en créant ces deux tables et en les remplissants avec le meme volume de donnée. Et votre requete ne prend que 64ms.

    Ce qui est étonnant dans votre résultat et c'est ce qui met ennormément de temps : c'est D1 NATURAL celà veut tout simplement dire qu'il n'utilise pas la clé primaire ni d'index pour la table Detail. Ce qui est tres ennuyeux. Car pour chaque enregistrement maitre il va scruter toute votre table detail pour trouver ceux qui correspondent...

    Verifiez que vous avez bien un index ou clé primaire sur le champ numerobon de votre table detail. (Si c'est le cas supprimez l index en question et recréez le.)

    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
    CREATE TABLE MAITRE (
        NUMEROBON    INTEGER NOT NULL,
        DATEBON      DATE,
        CODE_CLIENT  VARCHAR(6)
    );
     
    ALTER TABLE MAITRE ADD CONSTRAINT PK_MAITRE PRIMARY KEY (NUMEROBON);
     
    CREATE INDEX MAITRE_IDX1 ON MAITRE (DATEBON);
     
    CREATE TABLE DETAIL (
        NUMEROBON     INTEGER NOT NULL,
        CODE_PRODUIT  VARCHAR(10) NOT NULL,
        QTE_VENDU     NUMERIC(15,2),
        PU_VENTE      NUMERIC(15,2),
        BENEFICE      NUMERIC(15,2)
    );
     
    ALTER TABLE DETAIL ADD CONSTRAINT PK_DETAIL PRIMARY KEY (NUMEROBON, CODE_PRODUIT);
    la requete :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT  Sum(d1.benefice), count(*)
    FROM Detail  D1 inner join Maitre d on d.numerobon=d1.numerobon
    WHERE D.DateBon Between '2000/01/01' and '2006/01/01'
    Le plan utilisé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PLAN JOIN (D INDEX (MAITRE_IDX1),D1 INDEX (PK_DETAIL))
    Maitre_IDX1 étant l index sur dateBon.

  10. #10
    Membre actif Avatar de touhami
    Inscrit en
    Avril 2002
    Messages
    327
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 327
    Points : 264
    Points
    264
    Par défaut
    Bonjour,
    Merci Barbibulle , et je vais tester cela ce soir.

  11. #11
    Membre actif Avatar de touhami
    Inscrit en
    Avril 2002
    Messages
    327
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 327
    Points : 264
    Points
    264
    Par défaut
    Bonjour,
    j'ai suivie les etapes du Barbibulle , et ça marche tres bien.
    Merci a tous.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 31/05/2007, 08h24
  2. récuperer une variable d'une requéte de selection
    Par foufa007 dans le forum JDBC
    Réponses: 2
    Dernier message: 03/05/2007, 23h21
  3. Exécution trop longue d'une requête
    Par lodan dans le forum Requêtes
    Réponses: 5
    Dernier message: 13/10/2006, 16h34
  4. Sous-requête excutée plusieurs fois dans une requête
    Par sheridan31 dans le forum Oracle
    Réponses: 8
    Dernier message: 03/07/2006, 17h18

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