Jeg har et problem. Jeg skal trække en del data ud fra en ascii fil og nedenstående script gør det rigtig men det tager laang tid. Er der nogen der kan se hvordan jeg kan optimere mit script så det går lidt hurtigere.
' Åbner en connection til ascii filen Dim fso,f,filespec Set fso = CreateObject("Scripting.FileSystemObject") filespec = Server.Mappath("Min tekst fil") Set f = fso.OpenTextFile(filespec,1)
Dim LinieP,arrP,RS3
'Funktion der fjerne evt ' omkring navne function ReplaceP (arrP) ReplaceP = Replace(Replace(arrP,"""",""),"'","") end function
'Skal kun læse hvor 1. tal er 1 Do While not f.AtEndOfStream LinieP = f.ReadLine If Left(LinieP, 1) = "1" Then
'Laver et array der splitter linjer til senere udtræk fra db arrP = Split(LinieP,",")
'Henter alt fra db hvor produkter er ens Set RS3 = Conn.execute("Select * from Produktabel where ProduktNr = '"&arrP(1)&"'") IF not RS3.EOF Then
'Indsætter nye menuer Conn.execute("Insert into Produktabel(ProduktNr,MenuNr,ProduktNavn,ProduktNavnDK,Pris,Image,Offer,Godkendt) VALUES ('"&ReplaceP(arrP(1))&"','"&ReplaceP(arrP(2))&"','"&ReplaceP(arrP(3))&"','"&ReplaceP(arrP(4))&"','"&ReplaceP(arrP(5))&"','"&ReplaceP(arrP(6))&"','"&ReplaceP(arrP(7))&"','"&ReplaceP(arrP(8))&"')") end if RS3.close Set RS3 = Nothing End If Loop
Jeg ved ikke ligefrem om det hjælper fedt på din performance ( du er nødt til at gå i databasen for hver linie i din fil ) men der er ingen grund til at disse to linier: Set RS3 = Conn.execute("Select * from Produktabel where ProduktNr = '"&arrP(1)&"'") RS3.close skal udføres for hver linie i din fil.
Hvis du erklærer og åbner dit recordset på følgende måde: Set RS3 = Server.CreateObject("ADODB.Recordset") RS3.Open str, Conn, adOpenStatic
- hvor str er din sql, så kan du erklære dit recordset i toppen, sætte det til Nothing i bunden, og så nøjes med at åbne og lukke det i din løkke.
Og så ved jeg ikke om du ikke bruger ekstra ressourcer på at have din egen Replace-metode som du kalder i stedet for at kalde Replace() direkte - men som jeg se det er det da et ekstra kald der udføres 8-9 gange for hver linie...
Synes godt om
Slettet bruger
25. november 2003 - 13:34#3
Hvis vi nu udelukker visse features i scriptet er der så en måde man kan køre scriptet uden at skulle åbne for linje?
Eksempelvis hvis man kunne sammenligne txt filen og databasen og opdatere i et huk?
Jeg sad lige og tænkte på om der i din tabel vil være poster som ikke er i din fil ? Fordi ellers kunne det vise sig at være hurtigere at slette tabellen og derefter indsætte dine linier - du ville slippe for løkken og inserts tager ikke så lang tid. Men du ved bedst selv om der på denne måde vil være risiko for fejl ( kan din fil indeholde fejl osv.), fordi hvis det går rigtig galt har du jo ikke så mange data tilbage i din tabel... Men hilken database arbejder du med, og ligger dit filformat fast eller kan der være udsving hvis du er uheldig?
Jo du har lavet din egen replaceP(), indeni den kalder du VBScript's egen Replace(). I din sql: ('"&ReplaceP(arrP(1))&"','"& osv I stedet for: ('"&Replace(Replace(arrP(1),"""",""),"'","")&"','"&
Ovenstående ser selvfølgelig ikke pænt ud - alternativt kan du hente variable ud fra dit array før du danner din sql: var1 = Replace(Replace(arrP(1),"""",""),"'",""), og så bruge var1 i din sql - og det samme med de andre variable selvfølgelig, det vil gøre det mere overskueligt.
Fordi hvis din databse kan forstå exists-statements så burde du kunne mærke en forbedring af performance ved at bruge en sådan - du slipper nemlig for at åbne og lukke et recordset hver gang og det gør den langsom - det er ikke nødvendigvis selve løkken som jeg lige kom til at skrive - men det der sker i den...
Jamen så burde den kunne forstå det. Altså prøv så at indsætte: sql = "if exists(select ProduktNr from Produktabel where produktNr = '"&arrP(1)&"'") Begin Update Produktabel Set MenuNr = '"&ReplaceP(arrP(2))&"',ProduktNavn = '"&ReplaceP(arrP(3))&"', ProduktNavnDK = '"&ReplaceP(arrP(4))&"', Pris = '"&ReplaceP(arrP(5))&"',Image = '"&ReplaceP(arrP(6))&"', Offer = '"&ReplaceP(arrP(7))&"', Godkendt = '"&ReplaceP(arrP(8))&"' where ProduktNr = '"&arrP(1)&"' End Else Begin Insert Into Produkttabel (ProduktNr,MenuNr,ProduktNavn,ProduktNavnDK,Pris,Image,Offer,Godkendt) VALUES ('"&ReplaceP(arrP(1))&"','"&ReplaceP(arrP(2))&"','"&ReplaceP(arrP(3))&"','"&ReplaceP(arrP(4))&"','"&ReplaceP(arrP(5))&"','"&ReplaceP(arrP(6))&"','"&ReplaceP(arrP(7))&"','"&ReplaceP(arrP(8))&"') End"
Lige der hvor du åbner dit recordset, kommenter så alt med dit recordset + din IF-sætning ud og se hvad der sker. Skriv den evt ud og kør den direkte på databasen for at teste ) hurtigere og nemmere at fejlfinde syntaksfejl osv
Og dermed bliver din fulde kode: ' Åbner en connection til ascii filen Dim fso,f,filespec Set fso = CreateObject("Scripting.FileSystemObject") filespec = Server.Mappath("Min tekst fil") Set f = fso.OpenTextFile(filespec,1)
Dim LinieP,arrP,RS3
'Funktion der fjerne evt ' omkring navne function ReplaceP (arrP) ReplaceP = Replace(Replace(arrP,"""",""),"'","") end function
'Skal kun læse hvor 1. tal er 1 Do While not f.AtEndOfStream LinieP = f.ReadLine If Left(LinieP, 1) = "1" Then
conn.execute( "if exists(select ProduktNr from Produktabel where produktNr = '"&arrP(1)&"') Begin Update Produktabel Set MenuNr = '"&ReplaceP(arrP(2))&"',ProduktNavn = '"&ReplaceP(arrP(3))&"', ProduktNavnDK = '"&ReplaceP(arrP(4))&"', Pris = '"&ReplaceP(arrP(5))&"',Image = '"&ReplaceP(arrP(6))&"', Offer = '"&ReplaceP(arrP(7))&"', Godkendt = '"&ReplaceP(arrP(8))&"' where ProduktNr = '"&arrP(1)&"' End Else Begin Insert Into Produkttabel (ProduktNr,MenuNr,ProduktNavn,ProduktNavnDK,Pris,Image,Offer,Godkendt) VALUES ('"&ReplaceP(arrP(1))&"','"&ReplaceP(arrP(2))&"','"&ReplaceP(arrP(3))&"','"&ReplaceP(arrP(4))&"','"&ReplaceP(arrP(5))&"','"&ReplaceP(arrP(6))&"','"&ReplaceP(arrP(7))&"','"&ReplaceP(arrP(8))&"') End") 'Laver et array der splitter linjer til senere udtræk fra db arrP = Split(LinieP,",")
'Henter alt fra db hvor produkter er ens 'Set RS3 = Conn.execute("Select * from Produktabel where ProduktNr = '"&arrP(1)&"'") 'IF not RS3.EOF Then
'Indsætter nye menuer 'Conn.execute("Insert into Produktabel(ProduktNr,MenuNr,ProduktNavn,ProduktNavnDK,Pris,Image,Offer,Godkendt) VALUES ('"&ReplaceP(arrP(1))&"','"&ReplaceP(arrP(2))&"','"&ReplaceP(arrP(3))&"','"&ReplaceP(arrP(4))&"','"&ReplaceP(arrP(5))&"','"&ReplaceP(arrP(6))&"','"&ReplaceP(arrP(7))&"','"&ReplaceP(arrP(8))&"')") 'end if 'RS3.close 'Set RS3 = Nothing End If Loop
Nej det tror jeg ikke - du har jo flere linier der starter med 1..
Men har du prøvet at indsætte nogle response.write "<br>hertil1" & Now response.write "<br>hertil2"& Now eks. lige efter din do while og lige efter din execute. Bare for at se om det giver et hint om hvad der sløver den... Det kan jo være det vil hjælpe at indlæse filen på en anden måde - måske i et hug og derefter splitte på linieskift så du har et array fyldt med linier hvor du kan hente hver enkelt linie ud og opdatere med....
Jeg kan se at TextStream ( altså din variabel f ) har en metode der hedder readAll() hvis du nu læser den ind i en streng og derefter tester lidt på om du kan finde linieskift i din streng. Det kunne vel være chr(10) og chr(13) du skal forsøge at finde. Hvis du kan skifte dem ud med et tegn der ellers ikke er i filen og derefter splitte på det tegn til et array du kan køre din løkke på. Arrays er nemlig hurtige at arbejde med...jeg kender ikke hastigheden på readLine() men noget kører langsomt ved dig og der er ikke meget tilbage.
Hvordan tester du. Hjemmefra mod en eller anden server/et lejet domæne ?
Synes godt om
Slettet bruger
25. november 2003 - 15:19#25
jeg tror det der sløver den er 3900 produkter
det tager 16 sek på 512...spørgsmålet om er om det kan gøres hurtigere
Synes godt om
Slettet bruger
25. november 2003 - 15:21#26
lejet domæne mod udbyders server...jeg tænkte på at bruge read all men i dokumentationen skriver de at man skal bruge readline ved større filer da readall er meget ressource krævende...men et forsøg værd
Prøvede du at udskrive de to steder ? 1600 produkter - det vil sige 3900 updates - det er da ikke dårligt på 16 sek. ;-) - regn selv ud hvor mange pr. sek.
OK - er alle 3900 noget der er rettet ? Eller er der rettet i dem der starter med 1 ? Og kunne du evt lave det så filen kun indeholdt dem der skal rettes/indsættes ?
>>jean Jeg har fået mail om at du har kommenteret ? men får ikke noget frem... Jeg smutter lige om lidt men er tilbage fra imorgen tidlig om ikke andet ;-)
Nå det kan være de har ret ( i det med readAll ) - men har du så mulighed for at forkorte filen - lave noget forhånds-selektering ? Hvordan foregår det - er det noget med at brugeren sidder og retter, trykker på en knap og så venter på skal blive færdigt ?
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.