08. september 2003 - 18:20Der er
27 kommentarer og 1 løsning
Langsom kode - hvorfor?
Hey Jeg skriver nogle referencer ud fra en DB.
Nedenstående kode virker, men det tager ca. 8 sekunder inden min referenceliste vises på skærmen. Er der noget der er galt med nedenstående kode der gør den langsom? Der er ca. 200 poster i DB'en.
Hvis der yderlige info om en reference fx. video eller billder så vises et link til disse informationer. Det er der der sker i den if-sætning der begynder med: If (RS2.BOF Or RS2.EOF) AND ...
----------------- <% tid = session("tid")
if tid = "" OR tid = "Alle referencer" then strSQL = "SELECT * FROM Referencer ORDER BY tid DESC, id DESC;" else strSQL = "SELECT * FROM Referencer WHERE tid = '" & tid & "' ORDER BY tid DESC, id DESC;" end if
set rs = conn.execute(strSQL)
If (RS.BOF Or RS.EOF) Then response.write "Ingen referencer for denne i denne periode" else r = 0
Do Until rs.EOF tempID = rs("ID")
strSQL2 = "SELECT * FROM StortPicRef where referenceId = " & tempID & " ORDER BY largePic DESC;" set rs2 = conn.execute(strSQL2)
strSQL3 = "SELECT * FROM lillePicRef where referenceId = " & tempID & " ORDER BY smallPic DESC;" set rs3 = conn.execute(strSQL3)
strSQL4 = "SELECT * FROM VideoRef WHERE referenceId = " & tempID & ";" set rs4 = conn.execute(strSQL4)
%> HTML HTML <% If (RS2.BOF Or RS2.EOF) AND (RS3.BOF Or RS3.EOF) AND (RS4.BOF Or RS4.EOF) AND (g="xxx") Then %> HTML HTML <% else %> HTML HTML <% end if
RS.MoveNext r=1 loop
rs.Close Set rs = Nothing rs2.Close Set rs2 = Nothing rs3.Close Set rs3 = Nothing rs4.Close Set rs4 = Nothing Conn.Close set Conn = Nothing end if %>
Du må vise din fulde kode, hvis du looper med tre loopes, så tager det langt tid! Det kan optimeres med "order by", så recordsettet står i samme række følge som de skal udskrives. Du kan også optimere ved at lægge data over i nogen arrays, som giver et meget hurtigere gennemløb. Til sidst kan du også joine dine data i databasen, så du kun laver en select (her skal du sikre dig at felterne er indekseret..)
--->> stigc Fuld kode kommer her, kommentar under koden: -------------------- <% tid = session("tid")
if tid = "" OR tid = "Alle referencer" then strSQL = "SELECT * FROM Referencer ORDER BY tid DESC, id DESC;" else strSQL = "SELECT * FROM Referencer WHERE tid = '" & tid & "' ORDER BY tid DESC, id DESC;" end if
set rs = conn.execute(strSQL)
If (RS.BOF Or RS.EOF) Then response.write "Ingen referencer for denne i denne periode" else r = 0
Do Until rs.EOF 'r = 50 tempID = rs("ID")
strSQL2 = "SELECT * FROM StortPicRef where referenceId = " & tempID & " ORDER BY largePic DESC;" set rs2 = conn.execute(strSQL2)
strSQL3 = "SELECT * FROM lillePicRef where referenceId = " & tempID & " ORDER BY smallPic DESC;" set rs3 = conn.execute(strSQL3)
strSQL4 = "SELECT * FROM VideoRef WHERE referenceId = " & tempID & ";" set rs4 = conn.execute(strSQL4) %> <% if r = 0 then%> </center> <center> <%end if%> </center> <tr> <td width="377" bordercolor="#008000" valign="top" align="center"><font face="Tahoma" size="2"> <p align="left"><%=rs("bygherre")%></td> <center> <td width="118" bordercolor="#008000" valign="top"><font face="Tahoma" size="2"> <p align="left"><%=rs("sted")%></td> <td width="124" bordercolor="#008000" valign="top" align="center"><font face="Tahoma" size="2"><%=rs("tid")%></font> </td> <% b=rs("beskrivelse") if b <> "" then g="www" else g="xxx" end if
If (RS2.BOF Or RS2.EOF) AND (RS3.BOF Or RS3.EOF) AND (RS4.BOF Or RS4.EOF) AND (g="xxx") Then %> <td width="52" bordercolor="#008000" valign="top" align="center"><p align="center"><img border="0" src="noinfo.jpg"></p> <% else %> <td width="52" bordercolor="#008000" valign="top" align="center"><p align="center"><a href=vent.asp?Id=<%=rs("ID")%> target="_top"><img border="0" src="info.jpg"></a></p> <%end if%> </td> </tr>
<% RS.MoveNext r=1+r loop
rs.Close Set rs = Nothing rs2.Close Set rs2 = Nothing rs3.Close Set rs3 = Nothing rs4.Close Set rs4 = Nothing Conn.Close set Conn = Nothing end if%> -----------------------
Jeg looper kun over den ene forbindelse - RS ikke RS2, RS3 og RS4 de bliver kun brugt i en if then else sammenligning... Hvordan lægger jeg mine data i et array og løber det igennem?
Det kan betale sig at komprimere og reparer databasen i access, når den bliver lidt for stor. Det er min erfaring at den bliver hurtigere derved. Der er jo forskel på 1.5 mb og 456 kb f.eks.
OK nu ser jeg det. Du laver et loop med hvor du ekskverer en ny SQL for hvert trin. Det er ikke godt! Du må enten joine Referencer med de andre tabeller, eller lave din select's uden for loopet!
Ja, du foretager fire udtræk gange antal af poster i recordsættet "rs". Det kan hurtigt blive til rigtig mange, og det bryder Access sig bestemt ikke om.
Det kan godt være det er din access der driller men, for en hurtiger kode, bør du også bruge:
Option Explicit ' tvinger dig til at erklære dine variabler. Dim MyVar ' Erklæret variable. MyInt = 10 ' Hvor ikke erklærede variable generer fejl. MyVar = 10 ' og en erklæret variable ikke generer fejl.
Jeg har endnu ikke kunne påvise, at Option Explicit gør afviklingen hurtigere - blot at det giver bedre overblik over variabler og forhindrer tastefejl.
Ja, det er fordi jeg til hver post i tabellen "referencer" skal se om der er tilknyttet video eller billeder, det er det der afgører hvilket billede der skal vises i if-sætningen. Hvordan kan jeg eller lave det?
strSQL = "SELECT r.ID, s.referenceId As ref1, l.referenceId As ref2, v.referenceId As ref3 FROM ((Referencer r LEFT JOIN StortPicRef s ON r.ID = s.referenceId) LEFT JOIN lillePicRef l ON r.ID = l.referenceId) LEFT JOIN VideoRef v ON r.ID = v.referenceId ORDER BY r.tid DESC, r.id DESC;"
set rs = conn.execute(strSQL)
If IsNull(rs("ref1")) Then 'Ingen reference i StortPicRef ElseIf IsNull(rs("ref2")) Then 'Ingen reference i lillePicRef ElseIf IsNull(rs("ref3")) Then 'Ingen reference i VideoRef End If
-->> netro: Det virkede det blev det noget hurtigere af :) Men hvad er der der sker? Hvad sker der i SELECT-delen? Det er en forspørgsel det kan jeg se, men hvordan sker der i den.
- Jeg forstår ikke FROM delen med alle de der LEFT JOIN - Også heller ikke hvordan du bare kan spørge på IsNull(rs("ref1")) også vide der ingen StortPicRef er?
Kan du forklare det? Det ville være lækkert så man også lære lidt af det :)
Jeg kan give dig et lille eksempel her med udgangspunkt i følgende to tabeller.
Tabel1 ====== ID1 Navn 1 Bo 2 Ib 3 Per
Tabel2 ====== ID2 ID1 1 3 2 4 3 2
Lad os sige, vi nu er interesseret i at udtrække alle poster fra Tabel2 og samtidig se, om der er et navn i Tabel1, der relaterer til ID1.
SQL = "Select Tabel2.ID2, Tabel1.Navn From Tabel2 Left Join Tabel1 On Tabel2.ID1 = Tabel1.ID1" Set rs = Conn.Execute(SQL)
Hvis der ikke er noget navn i Tabel1, der relaterer til ID1 i Tabel2, vil rs("Navn") returnere NULL.
While Not rs.EOF If IsNull(rs("Navn")) Then Response.Write "Intet navn!<br>" Else Response.Write rs("Navn") & "<br>" End If rs.MoveNext Wend
Det vil give følgende udtræk:
Per Intet navn! Ib
Posten i Tabel2 hvor ID1 er lig 4, kan ikke finde et ID1 i Tabel1, der er lig 4. Derfor returneres NULL i stedet for et navn.
En LEFT JOIN tager alle poster fra den første tabel og dem, der har en relation fra den anden tabel. En INNER JOIN tager kun de poster, der kan relateres til hinanden mellem de to tabeller (fælles data).
Derudover findes der f.eks. RIGHT JOINS, LEFT/RIGHT NATURAL JOINS.
Jeg takker igen for din gode og præcise hjælp - det er rart at nogle kan se og løse openlyse fejl når man selv er gået fast. Jeg havde selv lavet en forespørgsel i Access, men det virker ikke nær så godt som det her! Tak!
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.