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

WinDev Discussion :

Optimisation requête SQL


Sujet :

WinDev

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : Maroc

    Informations forums :
    Inscription : Décembre 2002
    Messages : 211
    Points : 65
    Points
    65
    Par défaut Optimisation requête SQL
    Bonjour tout le monde,

    Pouvez-vous m'aider à optimiser, accélérer la vitesse d’exécution de cette requête;

    ça mat 1min à 2, et c'est énorme je crois.

    nombre d'enregistrement de Req_Art : 1000


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    POUR TOUT Req_Art 
    	sql1="select top 1 Lblivre.pu*(1-Lblivre.remise) as pu,  Bonlivra.date  from Lblivre Left outer join Bonlivra on Lblivre.nbl=Bonlivra.nbl WHERE Lblivre.code ='"+Req_Art.code+"' AND Bonlivra.valide='OUI'  AND Bonlivra.coclient='"+CodeCltFrs+"' order by date DESC "
    	SI PAS HExécuteRequêteSQL(Req1,hRequêteDéfaut,sql1) ALORS
    		HErreurInfo(HErreur())
    	FIN
    	HLitPremier(Req1)
    	sql2="update Req_Art set dprix ="+Req1.pu +" where Req_Art.code='"+Req_Art.code+"'"
    	SI PAS HExécuteRequêteSQL(req2,hRequêteDéfaut,sql2) ALORS
    		HErreurInfo(HErreur())
    	FIN
     
    FIN

    Merci d'avance..

  2. #2
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2009
    Messages
    1 278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 278
    Points : 2 153
    Points
    2 153
    Par défaut
    Citation Envoyé par ecoinfo Voir le message
    Bonjour tout le monde,

    Pouvez-vous m'aider à optimiser, accélérer la vitesse d’exécution de cette requête;

    ça mat 1min à 2, et c'est énorme je crois.

    nombre d'enregistrement de Req_Art : 1000


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    POUR TOUT Req_Art 
    	sql1="select top 1 Lblivre.pu*(1-Lblivre.remise) as pu,  Bonlivra.date  from Lblivre Left outer join Bonlivra on Lblivre.nbl=Bonlivra.nbl WHERE Lblivre.code ='"+Req_Art.code+"' AND Bonlivra.valide='OUI'  AND Bonlivra.coclient='"+CodeCltFrs+"' order by date DESC "
    	SI PAS HExécuteRequêteSQL(Req1,hRequêteDéfaut,sql1) ALORS
    		HErreurInfo(HErreur())
    	FIN
    	HLitPremier(Req1)
    	sql2="update Req_Art set dprix ="+Req1.pu +" where Req_Art.code='"+Req_Art.code+"'"
    	SI PAS HExécuteRequêteSQL(req2,hRequêteDéfaut,sql2) ALORS
    		HErreurInfo(HErreur())
    	FIN
     
    FIN

    Merci d'avance..
    Je connais pas trop TOP en sql mais as tu essayé avec un LIMIT 0,1 à la place ?

    Ensuite vérifie tes index et aussi traite les booléen comme des booléens plutôt que des chaines (je pense à valide='OUI' plutot que valide=1)

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 280
    Points : 12 974
    Points
    12 974
    Par défaut
    Bonjour,
    Je pense que la première optimisation à faire est de supprimer la boucle sur Req_Art, et de faire une sorte de boucler directement sur la première requête.
    Ainsi tu ne lances dans la boucle qu'une requête de mise à jour.
    D'ailleurs en toute rigueur il faut supprimer les deux tests sur BonLivra de la clause WHERE et les mettre dans la jointure, sinon la jointure externe ne sert à rien.
    De plus, tu fais une jointure externe sur BonLivra, mais tu ne t'en sers pas dans la requête (les calculs ne portent que sur lblivre), donc je me demande bien à quoi sert cette table ici...

    La requête deviendrait:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    select Lblivre.code ,Lblivre.pu*(1-Lblivre.remise) as pu
    from Lblivre

    Tatayo.

  4. #4
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2009
    Messages
    1 278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 278
    Points : 2 153
    Points
    2 153
    Par défaut
    Citation Envoyé par tatayo Voir le message
    Bonjour,
    Je pense que la première optimisation à faire est de supprimer la boucle sur Req_Art, et de faire une sorte de boucler directement sur la première requête.
    Ainsi tu ne lances dans la boucle qu'une requête de mise à jour.
    D'ailleurs en toute rigueur il faut supprimer les deux tests sur BonLivra de la clause WHERE et les mettre dans la jointure, sinon la jointure externe ne sert à rien.
    De plus, tu fais une jointure externe sur BonLivra, mais tu ne t'en sers pas dans la requête (les calculs ne portent que sur lblivre), donc je me demande bien à quoi sert cette table ici...

    La requête deviendrait:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    select Lblivre.code ,Lblivre.pu*(1-Lblivre.remise) as pu
    from Lblivre

    Tatayo.
    Bien vu j'avais pas fais gaffe à la restriction WHERE + jointure externe.... classique !

  5. #5
    Membre chevronné Avatar de EDM-TAHITI
    Homme Profil pro
    Directeur Service informatique et projet développement
    Inscrit en
    Janvier 2010
    Messages
    994
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Directeur Service informatique et projet développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2010
    Messages : 994
    Points : 1 998
    Points
    1 998
    Par défaut
    Hello,
    En plus, dans le code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SI PAS HExécuteRequêteSQL(Req1,hRequêteDéfaut,sql1) ALORS
    HErreurInfo(HErreur())
    FIN
    HLitPremier(Req1)
    Ajouter

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SI PAS HExécuteRequêteSQL(Req1,hRequêteDéfaut,sql1) ALORS
    HErreurInfo(HErreur())
    FIN
    HLitPremier(Req1 , hsansrafraichir)
    Cela evite à la requete de se relancer une seconde fois (si, si....)
    Et cela gagne du temps...

    [/CODE]

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : Maroc

    Informations forums :
    Inscription : Décembre 2002
    Messages : 211
    Points : 65
    Points
    65
    Par défaut
    Bonjour

    pour tatayo

    le deuxième fichier Bonlivra me permet de sélectionner que les enregistrements d'un client.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Bonlivra.coclient='00001'
    par exemple

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 280
    Points : 12 974
    Points
    12 974
    Par défaut
    Mais je ne vois pas l'intérêt, car tu fais une jointure externe (donc tu ne prends pas que les livraisons de ce client), et de plus tu n'utilises pas cette table dans les calculs.

    Tatayo.

  8. #8
    Membre expert
    Avatar de Emmanuel Lecoester
    Profil pro
    Inscrit en
    Février 2003
    Messages
    1 493
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Février 2003
    Messages : 1 493
    Points : 3 266
    Points
    3 266
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    select top 1 Lblivre.pu*(1-Lblivre.remise) as pu,  
             Bonlivra.date  
    Left outer join Bonlivra on Lblivre.nbl=Bonlivra.nbl 
                                 AND Bonlivra.valide='OUI'  
                                 AND Bonlivra.coclient= CodeCltFrs
    WHERE Lblivre.code = Req_Art.code
    order by date DESC
    en fait là pour chaque Lblivre.nbl, tu va parcourir TOUTE la table Bonlivra pour trouver une équivalence...
    pour ton produit cartésien vu que çà correspond quasi à çà tu vas filtrer...

    première proposition :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    select top 1 Lblivre.pu*(1-Lblivre.remise) as pu,  
             Bonlivra.date  
    from Lblivre 
    Left outer join Bonlivra on Lblivre.nbl=Bonlivra.nbl 
                                 AND Bonlivra.valide='OUI'  
                                 AND Bonlivra.coclient= CodeCltFrs
    WHERE Lblivre.code = Req_Art.code
    order by date DESC
    tu fais tes filtres dans le sous ensemble qui sera en left outer join.

    coté index :
    il te faut un index sur Lblivre.code vu que tu fais une égalité dans ta requete
    il te faut un index sur Bonlivra.nbl (normalement il doit exister naturellement vu que c'est une clé étrangère) et pour le top ce serait un index sur Bonlivra.nbl+Bonlivra.coclient.
    Je ne te fais pas le coup de la colonne booleenne valide qui prend OUI ou NON car coté perf en base comparer un booleen et une chaine de caractères c'est pas le même temps

    c'est quoi la fonction "top 1" ?

    En espérant te mettre sur le bon chemin.

    EDIT : en relisant ton code avec un req_art + un select + un update ta table s'en prend pas mal dans la figure.
    En full sql çà ferait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    update Req_Art 
    set dprix = (select top 1 Lblivre.pu*(1-Lblivre.remise) as pu
                    from Lblivre 
                    Left outer join Bonlivra on Lblivre.nbl=Bonlivra.nbl 
                    WHERE Lblivre.code = Req_Art.code
                    AND Bonlivra.valide='OUI'  
                    AND Bonlivra.coclient= CodeCltFrs
                    order by date DESC)
    where exists (select 1 from Lblivre where Lblivre.code = Req_Art.code)
    tu n'updates que les code qui existent dans Lblivre.

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : Maroc

    Informations forums :
    Inscription : Décembre 2002
    Messages : 211
    Points : 65
    Points
    65
    Par défaut
    Bonjour
    c'est exactement ce que je voulais mais
    erreur à l’exécution

    la date n'existe pas dans select


    exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    update Req_Art set dprix = (select top 1 Lblivre.pu*(1-Lblivre.remise) as pu from Lblivre  Left outer join Bonlivra on Lblivre.nbl=Bonlivra.nbl  WHERE Lblivre.code =Req_Art.code AND Bonlivra.valide='OUI'   AND Bonlivra.coclient='000699' order by date DESC) where exists (select 1 from Lblivre where Lblivre.code = Req_Art.code)

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : Maroc

    Informations forums :
    Inscription : Décembre 2002
    Messages : 211
    Points : 65
    Points
    65
    Par défaut
    Bonjour

    en effet c'est un problème avec windev qui n’accepte pas de select après le Set
    http://doc.pcsoft.fr/fr-fr/?2034001


    avez vous une idée de comment y remédier?

    Merci d'avance..

  11. #11
    Membre expert
    Avatar de Emmanuel Lecoester
    Profil pro
    Inscrit en
    Février 2003
    Messages
    1 493
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Février 2003
    Messages : 1 493
    Points : 3 266
    Points
    3 266
    Par défaut
    ben la technique que tu as fait :

    Pour tous les Req_Art
    Update unitaire

    ou bien encore
    tu crée une table (fichier au sens HF) contenant tes articles et leur nouveaux prix (la partie select)
    tu updates tes prix

    C'est chiant de trouver des parades quand on peut trouver des solution en full sql

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

Discussions similaires

  1. Optimisation requête SQL
    Par ludo00002 dans le forum SQL
    Réponses: 2
    Dernier message: 06/10/2008, 09h01
  2. Comment optimiser requête SQL avec création Index
    Par schumi101 dans le forum SQL
    Réponses: 25
    Dernier message: 11/12/2007, 21h28
  3. optimisation requête SQL
    Par marti dans le forum Oracle
    Réponses: 4
    Dernier message: 27/04/2006, 08h54
  4. Besoin d'aide pour optimiser requête SQL
    Par Keuf95 dans le forum Langage SQL
    Réponses: 10
    Dernier message: 06/09/2005, 16h02
  5. optimisation requête SQL!!! help!!
    Par anathem62 dans le forum Requêtes
    Réponses: 2
    Dernier message: 24/05/2004, 16h26

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