Just nu i M3-nätverket
Gå till innehåll

Optimera kod


martinwahlby

Rekommendera Poster

Är det något speciellt man ska tänka på när man programmerar asp och kopplar till accessdatabaser för att optimera koden, jag menar var ska man akta sig för, vilka fällor kan man fastna i?

 

Tips någon?

Länk till kommentar
Dela på andra webbplatser

Japp. Akta dig för att hämta onödigt stora mängder data ur databasen. Själv behövde jag bara lägga till en liten WHERE för att ändra

Skriptkörningen tog: 14.98 sekunder till Skriptkörningen tog: 0.31 sekunder.

Ganska skrattretande miss av mig - men svårupptäckt dock. :/

 

:: NoiseKiller, för en tystare datormiljö :: behöver mer Cola

 

Länk till kommentar
Dela på andra webbplatser

För att optimera rejält.

 

Skippa Access. Använd en riktig databas, tex MS-SQL, MySQL, Oracle, DB2 etc

 

Lägg endast "presentationskod" i ASP, "databaskod" bör du lägga i databasen i form av Stored Procedures (tyvärr stöder inte MySQL det i dagsläget).

 

 

 

Länk till kommentar
Dela på andra webbplatser

Yes, skillnaden mellan typ Access och MS-SQL är skrattretande....

 

Ett litet tips från mina gamla ASP-dagar var att många av mina kära kollegor (och för några år sen, jag med) var alldeles för bra på att bygga sidor som connectade och hämtade data typ 40 ggr per sida.

 

Ganska vanligt när man gör tabeller, tex ett forum där många gör:

1) Hämta alla forum

2) per forum, hämta antal inlägg

3) ev tom hämta top 5 inlägg

etc etc

(ok, lite enkelt exempel, men vatusan)

 

Du kan tjäna hur mycket som helst på att kapa sånt här och bara hämta allt 1 gång, framförallt när du inte har bar connection-hantering.

 

/David

 

Länk till kommentar
Dela på andra webbplatser

skillnaden mellan typ Access och MS-SQL är skrattretande....

 

Öh? Hur menar du? Anser du att det är stor eller liten skillnad...?

 

Jag själv vill helst inte prata om dem samma dag.....

 

Länk till kommentar
Dela på andra webbplatser

Som sagt ASP är lätt att lära sig, svårare att bemästar.

 

Problemet är att många nybörjar kurser på nätet inte har en tanke på prestanda när man visar sina exempel.

 

Att rabbla upp alla saker du skall tänka på är lite jobbigt, men det viktigaste är det som kommit upp här.

 

1. Gör inte datamanipulation på servern om du kan göra det i databasen (dock inte alltid det bästa :) )

2. Hämta inte mer än nödvändigt.

3. Dela upp din kod som Andersson säger i flera skickt... Presentation/affärslogik/data

4. Undvik precis som david säger att gå flera gånger till databasen för att hämta data, hämta helst 1 gång/persida eller /per site

5. Läs om GetRows() och se om det hjälper dig.

6. använd aldrig recordset för att läggatill och updatera data utan gör det med SQL-satser

7. behöver du verkligen ASP på sidan, går det inte lika bra utan.

8. Har du data som du hämtar som inte förändras, spara den som ett recordset i en sessions-variabel så spar du kopplingen till databasen, kräver dock mer minne.

9. Fundera på om du skall skapa nya html-sidor från databasen när den updateras, istället för att generera sidor varje gång någon vill kolla något

 

osv osv

 

Det finns massor att tänka på och det mesta lär man sig under tiden, införska gärna en bok om prestanda för ASP, vet att wrox har en för ASP.NET de kanske har för ASP med..

- Magnus

-----------------------------------------------------

ju mer jag lär mig ju mer inser jag så lite jag kan

 

Länk till kommentar
Dela på andra webbplatser

Mitt ex-jobb handlade om just detta och jag gjorde en del tester. Nu hade jag visserligen en bestämd konfiguration att testa på så testresultaten gäller ju inte allmängiltigt men gav mig en bra fingervisning om vad som passade mig bäst.

 

Jag testade Access och MySQL (hade inte råd att testa MS SQL) och MySQL var snabbare på det testet jag gjorde (hämtade ett par nästlade recordset och loopade igenom dessa). Framförallt visade det sig när flera personer var inne samtidigt att Access lackade ur samtidigt som MySQL tuffade på.

 

Sen kom jag fram till att det var snabbare att använda:

1. OPTIONS EXPLICIT och deklarera alla variabler

2. response.buffer = true (default i IIS5?)

3. <!--METADATA TYPE="typelib" FILE="C:\Program Files\Common Files\System\ado\msado15.dll"--> istället för adovbs.inc

4. Set RS = Server.CreateObject(”ADODB.recordset”)

objRS.open strSQL, strConnstring, AdOpenForwardOnly, AdLockReadOnly, AdCmdText

istället för

SET RS connection.execute(strSQL)

(för att köra SELECT och bara skriva ut alla värden i följd)

 

5. Största vinsten gjordes genom att använda GetRows() men det råder delade meningar om det fast i mitt fall var det inget snack om saken.

 

Sen gäller det att skriva bra SQL-satser inga SELECT * FROM ... utan SELECT fält1, fält2 osv. och att använda TOP (access) eller LIMIT (MySQL) samt bra WHERE-villkor för att inte plocka ut mer data än man behöver. Stäng ditt RS och din connection så snabbt som möjligt.

 

Sist men inte minst, se till att tänka till ordentligt innan du designar din databas. Det är lättare att ställa bra SQL-frågor till en smart designad databas än en mindre smart.. Använd index på de fält som används i WHERE-delen (lite beroende på hur många poster det finns) och använd helst bara numeriska fält i WHERE och ORDER BY delen av din fråga.

 

Kanske hjälper lite?

 

/Niklas

 

Länk till kommentar
Dela på andra webbplatser

Delade meningar om GetRows() ?

 

I minst 80% av fallen så finns det ingenting som justifierar (ok, knappast svenska men...) overheaden (inte det heller) som man får av ett recordset (skärpning !)

 

Ett till tips är att använda OUTPUT parametrar i sps som bara returnerar ett värde.

 

Och ns: synd att du inte kunde prova MS-SQL eller Oracle, har snackat med en del killar som jobbar med high-volume databaser och mySQL går ner redigt när du börjar få mycket folk.

 

Ett par tusen connections i sekunden och voilá, ett par tusen missnöjda kunder.

 

Och Mr Andersson: Hoppas du var ironisk, annars kan man ju ta illa vid sig :-)

 

Själv sitter jag med en online bank fast jag numera sitter på mortgage-sidan. Det skulle vara kul egentligen att testa Access (eller tom mySQL) på ett gäng tusen connections per sek + allt som sker på baksidan (connections till Isabel, VISA, etc etc)... Undrar hur det skulle gå ...

 

/David

 

[Redigerar:]

 

Kom på en allvarlig sak också:

Tänk igenom indexen !

Jag hade suveräna problem med en av mina databaser för att ett geni för några år sen indexerade praktisk taget allt, på en OLTP-databas !!!!

Jag hade flera gig av index när jag började på OLTP-dbn men nästan ingenting på rapporterings-databaserna...(och tyvärr var det ingen som riktigt fattade varför jag bröt ihop och gick i golvet av skratt !)

[inlägget ändrat 2002-10-22 16:44:09 av David Färm]

Länk till kommentar
Dela på andra webbplatser

Delade meningar om GetRows() ?

 

Ja, jag har fått mothugg här på forumet ett par gånger när jag sagt att GetRows är det bästa sättet att vinna prestanda.

 

Jag har använt MS SQL vid andra tillfällen men just i detta fallet gick det inte att lösa. Och att testa i en annan miljö än den som resten av testen utfördes kändes inte som en bra lösning eftersom det var ett jämförande test.

 

/Niklas

 

[inlägget ändrat 2002-10-22 16:48:26 av ns]

Länk till kommentar
Dela på andra webbplatser

Du säger att mySQL inte klarar flera tusen connections i sekunden... Hur är det med access*? skulle en sida typ ett annonsforum gå otroligt segt om man hade låt säga 5000 besökare per dag och använde access-databaser?

 

*okej jag är ingen expert och har inte gått över till my eller msSQL än.

 

Mvh

Martin

 

Länk till kommentar
Dela på andra webbplatser

Men vad skulle hända, skulle allt gå otroligt segt?

 

Så du menar att allt arbete jag lagt ner den senaste tiden varit i onödan? Det är bara att börja om från början lr?

 

Länk till kommentar
Dela på andra webbplatser

Ja, det snabbar faktiskt upp även om det kan låta konstigt.

Om du sen dessutom använder OPTION EXPLICIT (som kräver att du deklarerar alla variabler) så minskar du risken att skriva någon variabel fel vilket snabbar upp felsökning enormt mycket på en sida med mycket kod.

 

/Niklas

 

Länk till kommentar
Dela på andra webbplatser

5000 besökare per dag är alldeles för mycket för en Accessdatabas. Men allt jobb är givetvis inte gjort i onödan. Du kan exportera/importera mellan de flesta olika databaser. Sen behöver du ändra dina connectionstrings men annars är det inga stora skillnader.

 

/Niklas

 

Länk till kommentar
Dela på andra webbplatser

I minst 80% av fallen så finns det ingenting som justifierar (ok, knappast svenska men...) overheaden (inte det heller) som man får av ett recordset (skärpning !)

 

I bland annat ADO 2.1 ADO programmers reference (www.wrox.com) så bevisas att recordset är snabbare än getrows().

 

Själv gjorde jag tester på det och konstaterade att det går snabbare att loopa igenom ett recordset med loop och .movenext än att göra om det till en array med getrows och sedan loopa igenom med For-sats.

 

Dock gäller det att ju fler värden som man plockar ut från databasen desto mer vinner getrows, eftersom det verkade som att det är just hämtningen av data med .fields() som tar tid inte att loopa igenom.

 

Men man måste testa för varje system för att få fram om det är bättre med getrows eller recordset.

 

- Magnus

-----------------------------------------------------

ju mer jag lär mig ju mer inser jag så lite jag kan

 

Länk till kommentar
Dela på andra webbplatser

Access kan hantera (utan för stora prestand försämringar) ca 10-15 samtidiga connections.

 

Om du har 5000 besökare på en dag så skulle det bli ungfär 4 i minuten, vilket inte är något problem. Nu är det ju inte så snällt att det blir utspriddt jämt över dygnet utan då får en peak mellan klockan 17-22 där säkert 80% av dina besökare kommer ligga.

det är 4000 besökare på 5 timmar. Det betyder 13 i minuten. Sedan får du räkna på hur länge de stannar, säg 10 minuter, då har du 130 samtidiga besökare på din site i minuten.

 

Nu betyder inte det att det är 130 samtidiga connections till databasen! Beroend på hur mycket databastrafik du har på din site och hur bra du skriver koden så kan du komma ner till 5-10 samtidig connections till databasen vid 130 samtidiga besökare, vilket access klara av...

 

Så för att inte göra dig mer klar över om access klara det eller ej, så beror det på vad siten innehåller, hur länge du tror en besökare stannar på siten, hur länge en besökare stannar på en sida, hur mycket data som hämtas från databasen och hur bra ASP-kod du skriver för att kunna bestämma om du klara dig med access eller ej.

 

Nu verkar det dock som om du tror att du får så mycket trafik och då blir det svårt att expandera med access, så då är det bättre att skaffa en annan db direkt istället, MySQL är ett mycket bra val istället för Access och klara mer last än access men har ändå sina nackdelar jämför med en "riktigt" db.

 

Access är inte bygg för att hantera många förfrågningar men är klart bättre än sitt rykte...

 

- Magnus

-----------------------------------------------------

ju mer jag lär mig ju mer inser jag så lite jag kan

 

Länk till kommentar
Dela på andra webbplatser

Early binding ger flera fördelar.

Men en är att tolken helt enkelt kan allokera minne för en specifik variabletyp och när du sedan använder den så pushar den helt enkelt in data. Passar datan inte så krashar det.

 

Med late binding så får du två (fler egentligen) problem,

1) Variabeln allokeras som Object vilket är betydligt större än vad som vanligtvis krävs = tar mer minne & längre tid

2) Läs & Skriv till variabeln kommer kräva en viss parsning iom att det inte är uppenbart vilken typ av data som ligger där.

 

Fast, såklart, ASP...Kanske borde ha skrivit detta i VB-forumet....

 

 

Länk till kommentar
Dela på andra webbplatser

4. Set RS = Server.CreateObject(”ADODB.recordset”)

objRS.open strSQL, strConnstring, AdOpenForwardOnly, AdLockReadOnly, AdCmdText

istället för

SET RS connection.execute(strSQL)

 

Jag är lite nyfiken på hur du kom fram till det?

 

Själv har jag testat följande kod som på inget sätt är vetenskapligt belagd.

 

<%
Dim oConn
Dim oRs
Dim sSQL

Dim tStart, tEnd

set oConn = server.createObject("ADODB.Connection")
oConn.open "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=northwind;Data Source=127.0.0.1"

sSQL = "select * from Customers"

tStart = Timer()
For iIndex = 0 to 5000
'set oRs = server.createobject("ADODB.Recordset")
'oRs.open sSQL, oConn, 0 , 1
set oRs = oConn.execute(sSQL)

oRs.close
set oRs = nothing
next
tEnd = Timer()

oConn.close: set oConn = nothing

response.write tEnd - tStart
%>

 

och där är set oRs = oConn.execute() snabbare än den andra varianten inte speciellt mycket men lite.

 

Så hur du kom fram till att ors.open är snabbare gör mig lite nyfiken...

 

- Magnus

-----------------------------------------------------

ju mer jag lär mig ju mer inser jag så lite jag kan

 

Länk till kommentar
Dela på andra webbplatser

Jag är lite nyfiken på hur du kom fram till det?

Jag testade på samma sätt som du fast inte 5000 gånger och jag skrev även ut posterna jag hämtade (likadant på båda sätten givetvis).

 

Jag använde MySQL och ingen oleDb-koppling så kanske dessa skillnader tillsammans med att jag skrev ut posterna också gjorde skillnaden i detta fallet. Så det är ju ytterligare ett bevis för att olika lösningar är olika bra beroende på lokala avvikelser i konfigurationer mm.

 

Men för mig var det skillnad att göra på det sättet.

 

/Niklas

 

Länk till kommentar
Dela på andra webbplatser

Sen får man inte glömma att arrayen man får med Getrows allokerar betydligt mindre minne än ett recordset - kan vara avgörande på servrar med hög belastning...

 

Länk till kommentar
Dela på andra webbplatser

Japp!

 

Kan ju vara så att till MySQL's ODBC drivrutin så är det bättre med rs.open än set rs...

 

Håller med dig att det är olika för olika system och man måste testa med de förutsättningar som man har...

 

- Magnus

-----------------------------------------------------

ju mer jag lär mig ju mer inser jag så lite jag kan

 

Länk till kommentar
Dela på andra webbplatser

Arkiverat

Det här ämnet är nu arkiverat och är stängt för ytterligare svar.

×
×
  • Skapa nytt...