Avatar billede da_darkside Nybegynder
22. juni 2005 - 00:03 Der er 21 kommentarer og
1 løsning

Optimering af kode

Er der nogen af jer som kan komme med nogen gode ideer til hvordan jeg kan optimere følgende, så den kommer til at køre bedre

<%
' DB connection

Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};User Id=admin;Password=;DBQ=" & Server.MapPath("rsPaging.mdb")

' records per page
recordsonpage = 50

' Reworked count
Set allrecordscount = Conn.Execute("Select count(*) as Found from tblItem")
allrecords    = allrecordscount("found")

' if offset is zero then the first page will be loaded
offset = request.querystring("offset")
if offset = 0 OR offset = "" then
  requestrecords = 0
else
  requestrecords = requestrecords + offset
end if

' opens database
set rs = conn.Execute("SELECT * FROM tblItem ORDER BY ItemID")

' reads first records (offset) without showing them (can't find another solution!)
hiddenrecords = requestrecords
do until hiddenrecords = 0 OR rs.EOF
  hiddenrecords = hiddenrecords - 1
  rs.movenext
  if rs.EOF then
    lastrecord = 1
  end if
loop
%>

<html>
<head>
  <title>CD Database</title>
  <meta http-equiv="author" content="Tranzity">
</head>
<body>

<table cellspacing="2" cellpadding="2" border="1" width="400">

<%
' prints records in the table
showrecords = recordsonpage
recordcounter = requestrecords
do until showrecords = 0 OR rs.EOF
recordcounter = recordcounter + 1
%>

<tr>
  <td><b><% = recordcounter %></b></td>
  <td><% = rs("ItemID") %></td>
  <td><% = rs("ItemName") %></td>
</tr>

<%
  showrecords = showrecords - 1
  rs.movenext
  if rs.EOF then
    lastrecord = 1
  end if
loop
%>

</table>

<p>

<table cellspacing="2" cellpadding="2" border="1" width="400">
<tr>
  <td><% if requestrecords <> 0 then %><a href="new2.asp?offset=<% = requestrecords - recordsonpage %>">Prev Page</a><% else %>Prev Page<% end if %></td>
  <td><% if lastrecord <> 1 then %>    <a href="new2.asp?offset=<% = requestrecords + recordsonpage %>">Next Page</a><% else %>Next Page<% end if %></td>
</tr>
<tr>
  <td colspan="2">pagelist:
<%
pagelist = 0
pagelistcounter = 0
do until pagelist >= allrecords 
  pagelistcounter = pagelistcounter + 1
%>
<a href="new2.asp?offset=<% = pagelist %>"><% = pagelistcounter %></a>
<%
  pagelist = pagelist + recordsonpage
loop
%>
  </td>
</tr>
</table>

<%
' Closes connection
rs.close
Conn.close
%>

</body>
</html>
Avatar billede busschou Praktikant
22. juni 2005 - 06:47 #1
Som jeg ser det tror jeg ikke der er meget at optimere
Det eneste uhensigtmæssige er at du først looper alle de elementer igennem som ikke skal vises, og dernæst alle dem som skal vises
Problemet er så at der ikke findes en LIMIT i access, ellers kunne du blot selecte de rigtige ved noget ala "select * from tabel limit min,max"
Du kan komme uden om det ved at lave en indlejret select ala:
"SELECT TOP min * FROM (SELECT TOP max * FROM tabel ORDER BY itemID ASC) ORDER BY itemID ASC;"
Derved får du kun de elementer ud som du rent faktisk skal vise på siden og du slipper for at lave dit første loop
Men der udover kan jeg ikke se hvad du mere skulle kunne optimere, måske nogen vil vide om en slags løkke er hurtigere end en anden, men det ved jeg ikke og jeg tror det vil være minimalt
Avatar billede fennec Nybegynder
22. juni 2005 - 08:23 #2
Du kan hente dine resultater med et recordset i stedet. Så får du flere muligheder til at flytte rundt i dine resultater.

set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open "select * from .....", Conn, 1
rs.move 10, adBookmarkFirst '<-- flyt til 10 række

Med dette kan du også lave "paging", som er den rigtige måde at gøre det på, men det kræver mere kode. Du kan læse om det her:
http://activedeveloper.dk/artikler/default.asp?articleid=31

ps. Det er ikke alle databaser der understøtter disse metoder. Det gælder f.eks. MySQL, hvorfor den har "limit" funktionen indbygget.
Avatar billede busschou Praktikant
22. juni 2005 - 08:27 #3
fennec >> hvorfor er det lige netop den "rigtige" måde at gøre det på frem for andre måder?
Avatar billede da_darkside Nybegynder
22. juni 2005 - 08:46 #4
fennec > kan egentlig ikke se hvorfor den måde er bedre :-(
Avatar billede da_darkside Nybegynder
22. juni 2005 - 08:47 #5
busschou > kan ikke rigtigt få det til at virke, måske jeg har misforstået et eller andet.... kan du ikke prøve at indsætte det du vil ændre i den samlede kode ?
Avatar billede busschou Praktikant
22. juni 2005 - 08:51 #6
Jeg har aldrig brugt fennecs metode, men har set den i brug mange steder. Så jeg har ingen anelse om hvad der er mest effektivt eller hvorfor det skulle være mere rigtigt. Men måske der er en fornuftig forklaring? For så "sluger jeg gerne kamelen" :o)

Prøver lige sætte det ind
Avatar billede busschou Praktikant
22. juni 2005 - 09:07 #7
Nu har jeg ikke lige mulighed for at teste det, men jeg vil mene sådan her cirka
-----------
<%
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};User Id=admin;Password=;DBQ=" & Server.MapPath("rsPaging.mdb")

recordsonpage = 50

Set allrecordscount = Conn.Execute("Select count(*) as Found from tblItem")
allrecords    = allrecordscount("found")

offset = request.querystring("offset")
if offset < 0 offset = "" then
  offset = 0
end if

max = cint(recordsonpage + offset)

set rs = conn.Execute("SELECT TOP "&offset&" * FROM (SELECT TOP "&max&" * FROM tblItem ORDER BY ItemID) ORDER BY ItemID")
%>

<html>
<head>
  <title>CD Database</title>
  <meta http-equiv="author" content="Tranzity">
</head>
<body>

<table cellspacing="2" cellpadding="2" border="1" width="400">

<%
count = offset
do until rs.EOF %>

<tr>
  <td><b><% = count %></b></td>
  <td><% = rs("ItemID") %></td>
  <td><% = rs("ItemName") %></td>
</tr>

<%
  count = count + 1
  rs.movenext
loop
%>

</table>

<p>

<table cellspacing="2" cellpadding="2" border="1" width="400">
<tr>
  <td><% if offset <> 0 then %><a href="new2.asp?offset=<% = cint(offset - recordsonpage) %>">Prev Page</a><% else %>Prev Page<% end if %></td>
  <td><% if count < allrecordscount then %>    <a href="new2.asp?offset=<% = cint(offset + recordsonpage) %>">Next Page</a><% else %>Next Page<% end if %></td>
</tr>
<tr>
  <td colspan="2">pagelist:
<%
pagelist = 0
pagelistcounter = 0
do until pagelist >= allrecords
  pagelistcounter = pagelistcounter + 1
%>
<a href="new2.asp?offset=<% = pagelist %>"><% = pagelistcounter %></a>
<%
  pagelist = pagelist + recordsonpage
loop
%>
  </td>
</tr>
</table>

<%
rs.close
Conn.close
%>

</body>
</html>
------
Avatar billede busschou Praktikant
22. juni 2005 - 09:12 #8
Der er lige et par småting
if offset < 0 offset = "" then
bør være
if offset = "" or cint(offset) = 0 then
og
<td><% if offset <> 0 then %><a href="new2.asp?offset=<% = cint(offset - recordsonpage) %>">Prev Page</a><%
bør være
<td><% if offset < 0 then %><a href="new2.asp?offset=<% = cint(offset - recordsonpage) %>">Prev Page</a><%
--
Men håber du ellers kan se ideen i det?
Avatar billede busschou Praktikant
22. juni 2005 - 09:14 #9
sikke noget pladder
Den sidste skal være
<% if offset > 0 then %>
--
kan være du får andre slå fejl, men jeg tror det vil virke
Det eneste jeg reelt er i tvivl om det er hvordan access reagerer hvis TOP max er for stor
Dvs hvis man beder om fx TOP 100 og der kun er 50 records, om den så giver det hele...eller...hmm
Men det kan løses ved at lave et tjek på max
if max > allrecords then
  max = allrecords
end if
Avatar billede fennec Nybegynder
22. juni 2005 - 09:18 #10
busschou >>
Jeg mener "rigtig" i den forstand at det er funktioner bygget direkte til dette formål. Men selvfølgelig kan det laves på andre måder også :o)
Avatar billede busschou Praktikant
22. juni 2005 - 09:34 #11
fennec >> ok, har bare aldrig rigtig sat mig ind i det, måske fordi jeg ikke er meget for access ;o) - men hvis de er direkte lavet med det til formål, ja så må de jo også være optimeret til det formål, og så er det måske værd at overveje at bruge :o)
Avatar billede fennec Nybegynder
22. juni 2005 - 09:59 #12
Bruger skam heller ikke access selv, men det virker heldigvis også i MS-SQL :o)

Man får så mange flere muligheder, nå man åbner gennem et recordset, men jeg har aldrig forstået det at opretter/ændre data gennem et recordset, som nogle gør. Man undgår vist ' problemet, dato konvertering og kommatal problemet, men jeg holder mig nu til sql-sproget. Det synes jeg er mere logisk.
Avatar billede busschou Praktikant
22. juni 2005 - 10:13 #13
Det er også lidt typisk M$ at lave sit eget frem for optimere på standarden ;o)
Avatar billede da_darkside Nybegynder
22. juni 2005 - 12:00 #14
Det virker hvis ikke helt med den select:-(

Fejltype:
Microsoft OLE DB Provider for ODBC Drivers (0x80040E14)
[Microsoft][ODBC Microsoft Access-driver] SELECT-sætningen indeholder et reserveret ord eller argument, der er stavet forkert eller mangler, eller tegnsætningen er ikke korrekt.
/rsPaging/new3.asp, line 17
Avatar billede busschou Praktikant
22. juni 2005 - 12:26 #15
ok det kan jeg ikke umiddelbart se hvad skyldes.. prøv gøre sådan her så den skriver den ud før den eksekverer den
--
sql = "SELECT TOP "&offset&" * FROM (SELECT TOP "&max&" * FROM tblItem ORDER BY ItemID) ORDER BY ItemID"
response.write sql
set rs = conn.Execute(sql)
Avatar billede da_darkside Nybegynder
22. juni 2005 - 22:08 #16
når jeg skriver den ud bliver det

SELECT TOP * FROM (SELECT TOP * FROM tblItem ORDER BY ItemID) ORDER BY ItemID

men får stadig følgend fejl
Fejltype:
Microsoft OLE DB Provider for ODBC Drivers (0x80040E14)
[Microsoft][ODBC Microsoft Access-driver] SELECT-sætningen indeholder et reserveret ord eller argument, der er stavet forkert eller mangler, eller tegnsætningen er ikke korrekt.
/rsPaging/new3.asp, line 23
Avatar billede busschou Praktikant
22. juni 2005 - 23:10 #17
ok det vil så sige at den ikke får din MIN og MAX værdi med som jeg kan se det
Prøv at definere følgende under definitionen af recordsonpage
offset = 0
max = recordsonpage
Så bør de være defineret uanset om der er noget i querystringen eller ej
Det vil så sige at hvis ikke offset er sat så bør den vælge min=0 og max=50
Avatar billede fennec Nybegynder
23. juni 2005 - 11:19 #18
Må jeg anbefale min ide fra 22/06-2005 08:23:11. Du skal så bare udskifte dette:

set rs = conn.Execute("SELECT * FROM tblItem ORDER BY ItemID")
' reads first records (offset) without showing them (can't find another solution!)
hiddenrecords = requestrecords
do until hiddenrecords = 0 OR rs.EOF
  hiddenrecords = hiddenrecords - 1
  rs.movenext
  if rs.EOF then
    lastrecord = 1
  end if
loop

med dette:

set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open "SELECT * FROM tblItem ORDER BY ItemID", Conn, 1
hiddenrecords = requestrecords
rs.move hiddenrecords, adBookmarkFirst
Avatar billede da_darkside Nybegynder
24. juni 2005 - 21:06 #19
fennec > virker desværre stadig ikke koden er følgende

<%
' DB connection

Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Open "DRIVER={Microsoft Access Driver (*.mdb)};User Id=admin;Password=;DBQ=" & Server.MapPath("rsPaging.mdb")

' records per page
recordsonpage = 50

' Reworked count
Set allrecordscount = Conn.Execute("Select count(*) as Found from tblItem")
allrecords    = allrecordscount("found")

' if offset is zero then the first page will be loaded
offset = request.querystring("offset")
if offset = 0 OR offset = "" then
  requestrecords = 0
else
  requestrecords = requestrecords + offset
end if

set rs = Server.CreateObject("ADODB.RecordSet")
rs.Open "SELECT * FROM tblItem ORDER BY ItemID", Conn, 1
hiddenrecords = requestrecords
rs.move hiddenrecords, adBookmarkFirst
%>

<html>
<head>
  <title>CD Database</title>
  <meta http-equiv="author" content="Tranzity">
</head>
<body>

<table cellspacing="2" cellpadding="2" border="1" width="400">

<%
' prints records in the table
showrecords = recordsonpage
recordcounter = requestrecords
do until showrecords = 0 OR rs.EOF
recordcounter = recordcounter + 1
%>

<tr>
  <td><b><% = recordcounter %></b></td>
  <td><% = rs("ItemID") %></td>
  <td><% = rs("ItemName") %></td>
</tr>

<%
  showrecords = showrecords - 1
  rs.movenext
  if rs.EOF then
    lastrecord = 1
  end if
loop
%>

</table>

<p>

<table cellspacing="2" cellpadding="2" border="1" width="400">
<tr>
  <td><% if requestrecords <> 0 then %><a href="new2.asp?offset=<% = requestrecords - recordsonpage %>">Prev Page</a><% else %>Prev Page<% end if %></td>
  <td><% if lastrecord <> 1 then %>    <a href="new2.asp?offset=<% = requestrecords + recordsonpage %>">Next Page</a><% else %>Next Page<% end if %></td>
</tr>
<tr>
  <td colspan="2">pagelist:
<%
pagelist = 0
pagelistcounter = 0
do until pagelist >= allrecords 
  pagelistcounter = pagelistcounter + 1
%>
<a href="new2.asp?offset=<% = pagelist %>"><% = pagelistcounter %></a>
<%
  pagelist = pagelist + recordsonpage
loop
%>
  </td>
</tr>
</table>

<%
' Closes connection
rs.close
Conn.close
%>

</body>
</html>
Avatar billede da_darkside Nybegynder
12. juli 2005 - 01:02 #20
ingen ideer overhovedet ?
Avatar billede fennec Nybegynder
12. juli 2005 - 08:26 #21
Jeg kan ikke helt forstå det ikke virker, men der kan selvfølgelig være omstændigheder der gør det :o)

Min sidste ide er at du skal ændre hele siden, så den følger opbygningen fra det link til activedeveloper, jeg havde min første post. Men det betyder så at du skal begynde helt forfra :(
Avatar billede da_darkside Nybegynder
15. januar 2006 - 21:34 #22
hmm kom ikke videre dengang
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester