Un moyen pour rendre mon prog plus rapide ?

m1nus Messages postés 5 Date d'inscription mardi 8 avril 2003 Statut Membre Dernière intervention 18 septembre 2007 - 18 sept. 2007 à 19:00
m1nus Messages postés 5 Date d'inscription mardi 8 avril 2003 Statut Membre Dernière intervention 18 septembre 2007 - 18 sept. 2007 à 22:40
Bonjour,

Je viens solliciter votre aide car je me trouve face à un petit problème de lenteur de mon programme.

En fait, je dois créer un programme de statistiques dont les données proviennent de plusieurs bases de données indépendantes.
Ce que j'ai fait afin de rassembler toutes les données, c'est parcourir la plus grosse table avec un recordset, et pour chaque recordset, aller retrouver son équivalent dans les 3 autres tables indépendantes. Une fois les données recueillies, je les insère dans une nouvelle table temporaire qui me servira aux statistiques.

Seulement cela prend énormément de temps. En effet, ce sont des tables qui contiennent plusieurs milliers de lignes. Et les parcours sont donc nombreux.
J'ai essayé de 2 manières différentes, soit en recréant des accès aux 3 autres tables a chaque movenext du recordset de la table principale, soit en faisaint une requête plus générale des 3 tables et en les parcourant toutes a chaque recordset de la table principale.

Mais dans les deux cas c'est très (trop) lent (6-7 minutes pr générer 5-6000 lignes)

Je ne sais pas si j'ai été assez clair car le projet est un peu bancal à la base mais si vous pourriez m'aider ca serait vmt vmt sympa.

m1nu$

7 réponses

m1nus Messages postés 5 Date d'inscription mardi 8 avril 2003 Statut Membre Dernière intervention 18 septembre 2007
18 sept. 2007 à 19:21
Peut-être qu'un filtre sur les recordset des 3 tables en fonction du paramètre du recordset principal irait plus vite ?

Je ne sais pas si un filtre améliore la vitesse par rapport a un parcours de l'entièreté du recordset jusqu'a trouver la ligne désirée?

Merci d'avance...

m1nu$
0
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
18 sept. 2007 à 19:59
salut,

tes tables sont-elles indexées?
un bout de code (avec la récap du contenu des tables) pourrait nous aider à voir où çà pêche....

++
<hr size="2" width="100%" />Prenez un instant pour répondre à [infomsg_SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
0
m1nus Messages postés 5 Date d'inscription mardi 8 avril 2003 Statut Membre Dernière intervention 18 septembre 2007
18 sept. 2007 à 20:03
Non mes tables ne sont pas indexées, je les reçois telles quelles. Je peux rajouter un index par après ?

Mais une fois la raquête chargée dans le recordset, il n'y a plus d'accès à la table quand même ? Ou bien le recordset ne fait que le lien avec les enregistrements de la table?

Voici un bout de code (un peu brouillon excusez-moi, mais c'est fait en rush)

      sSQL = ("SELECT PROPDATE, MEMBERCODE, OPERATOR, BONDCODE, BONDTYPE, UPDTIME, BID_PRICE, ASK_PRICE, BID_YIELD, ASK_YIELD, BID_BLOCK_QTY, ASK_BLOCK_QTY, STATUS " & _
            "FROM Props_data_3_" & madate(2) & madate(1) & madate(0) & " " & _
            "WHERE MEMBERCODE = '" & bank.Value & "' " & _
            "AND STATUS = 0 " & _
            choixbond & _
            intervaltime & _
            allocated & _
            "ORDER BY MEMBERCODE, BONDCODE, UPDTIME DESC;")


    Set myRec = conn.Execute(sSQL)


    old_bond = ""
    old_member = ""
   
    sSQL = ("SELECT membercode, memberstatus, updatedate, updatetime " & _
            "FROM member " & _
            "WHERE membercode = '" & bank.Value & "' " & _
            "AND updatedate = #" & madate(1) & "/" & madate(0) & "/" & madate(2) & "# " & _
            "ORDER BY updatetime DESC;")
           
    Set myRec3 = conn3.Execute(sSQL)


    sSQL = ("SELECT membercode, traderstatus, updatetime " & _
            "FROM trader " & _
            "WHERE membercode = '" & bank.Value & "' " & _
            "AND updatetime LIKE '%" & madate(0) & "/" & madate(1) & "%' " & _
            "ORDER BY membercode, updatetime DESC;")
   
    Set myRec4 = conn3.Execute(sSQL)


    sSQL = ("SELECT Q.qty, Q.spread, A.member, A.bucket, A.bondcode " & _
            "FROM quotas Q, allocs A " & _
            "WHERE A.member = '" & bank.Value & "' " & _
            "AND A.bucket = Q.bucket " & _
            "ORDER BY 3, 4;")
           
    Set myRec5 = conn3.Execute(sSQL)


    Do Until myRec.EOF
   
        trad_stat = 0
        mem_stat = 0
        qty_stat = 0
        pr_stat = 0


        If (myRec!BID_PRICE >= myRec!ASK_PRICE) Then
            pr_spread = FormatNumber(myRec!BID_PRICE, 2) - FormatNumber(myRec!ASK_PRICE, 2)
        Else: pr_spread = FormatNumber(myRec!ASK_PRICE, 2) - FormatNumber(myRec!BID_PRICE, 2)
        End If


        If (myRec!BID_YIELD >= myRec!ASK_YIELD) Then
            yi_spread = myRec!BID_YIELD - myRec!ASK_YIELD
        Else: yi_spread = myRec!ASK_YIELD - myRec!BID_YIELD
        End If


        If ((old_bond myRec!bondcode) And (old_member myRec!MEMBERCODE)) Then
            duree = old_time - myRec!updtime
        Else: duree = 173000000 - myRec!updtime
        End If


        trouve = False


        Do Until myRec4.EOF Or trouve            If (CLng(Mid$(myRec4!updatetime, 12, 2) & Mid$(myRec4!updatetime, 15, 2) & Mid$(myRec4!updatetime, 18, 2) & Mid$(myRec4!updatetime, 21, 3)) <myRec!updtime) And (myRec4!traderstatus 1) Then
                Do Until myRec3.EOF Or trouve                    If (myRec3!updatetime <myRec!updtime) And (myRec3!memberstatus 1) Then
                        Do Until myRec5.EOF Or trouve                            If ((myRec5!member myRec!MEMBERCODE) And (myRec5!bondcode myRec!bondcode)) And (FormatNumber(pr_spread, 2) <= FormatNumber(myRec5!spread, 2)) And ((myRec!bid_block_qty >= myRec5!qty) Or (myRec!ask_block_qty >= myRec5!qty)) Then
                                sSQL = ("INSERT INTO props (PROPDATE, MEMBERCODE, OPERATOR, BONDCODE, BONDTYPE, UPDTIME, DURATION, BID_PRICE, ASK_PRICE, PRICE_SPREAD, BID_YIELD, ASK_YIELD, YIELD_SPREAD, BID_BLOCK_QTY, ASK_BLOCK_QTY) " & _
                                        "VALUES ('" & myRec!PROPDATE & "', '" & myRec!MEMBERCODE & "', '" & myRec!Operator & "', '" & myRec!bondcode & "', '" & myRec!bondtype & "', " & myRec!updtime & ", " & duree & ", " & myRec!BID_PRICE & ", " & myRec!ASK_PRICE & ", " & pr_spread & ", " & myRec!BID_YIELD & ", " & myRec!ASK_YIELD & ", " & yi_spread & ", " & myRec!bid_block_qty & ", " & myRec!ask_block_qty & ");")
                               Set myRec2 = conn2.Execute(sSQL)
                                trouve = True
                                cpt = cpt + 1
                            Else: myRec5.MoveNext
                            End If
                        Loop
                    Else: myRec3.MoveNext
                    End If
                Loop
            Else: myRec4.MoveNext
            End If
        Loop


        old_time = myRec!updtime
        old_bond = myRec!bondcode
        old_member = myRec!MEMBERCODE


        myRec.MoveNext
        myRec3.MoveFirst
        myRec4.MoveFirst
        myRec5.MoveFirst

m1nu$
0
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
18 sept. 2007 à 20:44
il doit manquer un loop à la fin non?

bref, ici en voulant trop réduire ton code, tu fais des traitements et des tests inutiles

comme tu boucles sans cesse, regarde bien tes if....
les conditions sont énormes, certains arguments sont trouvés (forcément, pour avoir 6000 lignes au final), mais PEUT-ÊTRE qu'en séparant chaque if, tu gagnerais du temps (au détriment de la lisibilité mais bon)

comme çà tu ne fais pas un test d'objets lourds pour rien.
reste aussi à voir qu'est-ce qui te semble (comme résultat) le plus fréquent (true), pour placer les conditions de manière justement à faire le moins de sauts possible

pour la grosse partie çà donne un truc de ce genre :

Dim sUpDateTime As String
Do Until myRec4.EOF Or trouve
    If (myRec4!traderstatus = 1) Then
        sUpDateTime = CStr(myRec4!updatetime)
        If (CLng(Mid$(sUpDateTime, 12, 2) & Mid$(sUpDateTime, 15, 2) & Mid$(sUpDateTime, 18, 2) & Mid$(sUpDateTime, 21, 3)) <= myRec!updtime) Then
            Do Until myRec3.EOF Or trouve
                If (myRec3!memberstatus = 1) Then
                    If (myRec3!updatetime <=
myRec!updtime) Then
                        Do Until myRec5.EOF Or trouve
                            If (myRec5!member = myRec!MEMBERCODE)
And (myRec5!bondcode =
myRec!bondcode) Then
                                If FormatNumber(pr_spread, 2) <= FormatNumber(myRec5!spread, 2) Then
                                    If (myRec!bid_block_qty >=
myRec5!qty) Or (myRec!ask_block_qty >= myRec5!qty) Then
                                        sSQL = ("INSERT INTO props (PROPDATE,
MEMBERCODE, OPERATOR, BONDCODE, BONDTYPE, UPDTIME, DURATION, BID_PRICE,
ASK_PRICE, PRICE_SPREAD, BID_YIELD, ASK_YIELD, YIELD_SPREAD, BID_BLOCK_QTY,
ASK_BLOCK_QTY) " & _
                                          "VALUES ('" & myRec!PROPDATE & "',
'" & myRec!MEMBERCODE & "', '" & myRec!Operator & "',
'" & myRec!bondcode & "', '" & myRec!bondtype & "',
" & myRec!updtime & ", " & duree & ", " & myRec!BID_PRICE & ",
" & myRec!ASK_PRICE & ", " & pr_spread & ", " & myRec!BID_YIELD & ",
" & myRec!ASK_YIELD & ", " & yi_spread & ", " & myRec!bid_block_qty & ",
" & myRec!ask_block_qty & ");")
                                        Set myRec2 =
conn2.Execute(sSQL)
                                        trouve = True
                                        cpt = cpt + 1
                                    Else
                                        myRec5.MoveNext
                                    End If
                                Else
                                    myRec5.MoveNext
                                End If
                            Else
                                myRec5.MoveNext
                            End If
                        Loop
                    Else
                        myRec3.MoveNext
                    End If
                Else
                    myRec3.MoveNext
                End If
            Loop
        Else
            myRec4.MoveNext
        End If
    Else
        myRec4.MoveNext
    End If
Loop

<hr size="2" width="100%" />Prenez un instant pour répondre à [infomsg_SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
m1nus Messages postés 5 Date d'inscription mardi 8 avril 2003 Statut Membre Dernière intervention 18 septembre 2007
18 sept. 2007 à 20:59
Merci pour l'aide, je vais tester ca demain matin dès que j'arrive au boulot.

Et pour les index, vous pensez que ca pourrait accélérer les recherches? Style au lieu de mettre :

Do Until myRec3.EOF Or trouve                    If (myRec3!updatetime <myRec!updtime) And (myRec3!memberstatus 1) Then

je mets un filtre :

myRec3.Filter = "(updatetime <= " & myRec!updtime & ") And (memberstatus = 1)"

Dans ce cas, le curseur va directement se placer à l'enregistrement qui convient et je ne devrai pas parcourir tout le recordset et faire les tests "IF THEN ELSE".

Ensuite, à la fin du 1er traitement je remets un filtre vide :

myRec3.Filter = ""

Encore merci pour tout

m1nu$
0
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
18 sept. 2007 à 21:33
beh c'est le but de l'index et du filtre donc çà devrait accelèrerer grandement
mais pas forcément pour remplacer TOUS les if ; le filtre prend aussi ses ressources...

ajoute des tests plus précis (tu peux encore séparer 2 fois sur myRec5!, avec un choix judicieux d'ordre des conditions, à mon avis tu peux réduire d'un tiers ou de moitié le temps d'execution oui

bon courage
<hr size="2" width="100%" />Prenez un instant pour répondre à [infomsg_SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
0
m1nus Messages postés 5 Date d'inscription mardi 8 avril 2003 Statut Membre Dernière intervention 18 septembre 2007
18 sept. 2007 à 22:40
Ok merci pour tout.

Je teste ca demain et je vous tiens au courant.

m1nu$
0
Rejoignez-nous