Jeg satte så nogle indexes op i mine tabeller, blandt andet i min messenger, med 200K rows (og 150 megs data). Med det samme kunne jeg se en enorm forøgelse af hastigheden, samtidig med at processor forbruget blev formindsket til 25% (fra 100%).
Det var jo helt fint, ingen problemer eller noget.
Men da jeg så kom til "rush hour", begyndte det at fryse! Jeg har modtaget rapporter om dette, såsom at det kører hurtigt i et par minutter, hvorefter det fryser et godt stykke tid igen. Nogle personer blev nødt til at vente 10 minuter mellem hver side (som de gerne skulle kunne loade hvert sekund)!!
Hvad kan grunden være? Hvorfor gør mine indexes at min side fryser?
deslige mener jeg at hvis du sætter mange indexes på én tabel, og der foretages mange updates, inserts, deletes på tabellen, så kan det påvirke perormance negativ, idet alle indexes skal justeres når data ændres....
en trace file skal du først selv lave vha. sql server profiler... Du sætter en trace op på db - lader den gøre 1 døgn eller 2 og så har du din trace file som index tuning wizarden kan bruge
ok... profiler. Hvordan gør jeg? Når jeg siger ny trace inde i profiler, skal jeg så save to file, eller til table? Hvis til table - hvad for en tabel?
du saver bare til en fil.... opret evt. et bibliotek hvortil du gemmer den. Når det er gjort starter du traceren hvis den da ikke selv gør det og venter x antal timer/dage - så har du din trace file. Og det er jo så din trace fil som du skal bruge i index tuning wizarden....
jeg har lige fået at vide at nogle personen kunne bruge siden perfekt hurtigt, mens andre slet ikke kunne...
kan det være at mine nye indexes har på en eller anden måde sat en limit på antallet af brugere, og er det sådan noget at den index tuning wizard ordner?
hmm... ved midnat, hvor det bliver brugt mest, er der vel 50 personer på... Det er i sig selv ikke så meget, men efter som de henter en ny side hvert 3 sekund, bliver det en del. Jeg trækker knap en halv million sider om dagen, med 5 opslag i en database på hver.
Serveren er en 1600 MhZ Pentium4, med 1 gig DDR ram... ret kraftig - og den bliver KUN brugt til det ene formål.
Inden du gør et eller andet drastisk synes jeg lige du skal slå kold vand i blodet - lav først og fremmest en index tuning - med det antal sidevisninger / selects vil det være at foretrække... Dernæst synes jeg du skal analysere de problemer der bliver indrapporteret - måske sidder halvdelen på en sløv isdn forb. el. andet....
ved at køre SELECT @@MAX_CONNECTIONS i query analyzeren kan du se hvor mnage samtidige connection der kan være til din sql server...
ok, jeg prøvede at køre den der index tuning efter ca. 15 minutter... bare for at den kunne tage sig af det værste; det er det samme der bliver gjort i løbet af en hel dag.
Det den gjorde, var blandt andet at lave et clusteret index, som jeg også selv gjorde i starten da jeg ville optimere det. Det gav et løft i hastigheden, men laver samtidig en fejl:
Microsoft OLE DB Provider for SQL Server error '80040e31'
Timeout expired
/messenger.asp, line 109
På den linie er der:
dbConnection.execute "UPDATE messenger_messages SET new = 0 WHERE [to] = '"&membername&"' AND folder = "&folder
den der er sat til clusteret er feltet "to". Hvorfor timer den ud der? det kan jeg ikke forstå :s når jeg slår clusteret fra, virker det igen, dog en smule langsommere.
ok, jeg fandt ud af en løsning, men forstår ikke hvorfor den gør det! Da jeg satte den sætning ned under hvor mit recordset bliver lukket, virker det igen. Førhen betød det dog intet om mit recordset var åbent eller lukket i den forbindelse!?
nu ved jeg jo ikke hvad sistet består af etc., men jeg kan forestille mig der er en masse selects.... ligger disse i en stored procedure? Hvis ikke ville det være til gavn for sitets performance...
nææ, de ligger ikke en en stored procedure :( Har endnu ikke lært hvordan det gøres. Det jeg tror der tager mest kræfter, er at serveren på hver side skal tjekke om en person har fået nogen nye meddelelser, hvor mange og hvor... Min kode virker ret upraktisk, og jeg vil egentligt tro at alt det kunne gøres i en stored procedure!?
Jeg ligger den ind her:
'changing to messenger strSQL2 = "SELECT folder, Count(folder) as rcount FROM messenger_messages WHERE [to] = '"&membername&"' AND new = 1 AND folder in (1,4) GROUP BY folder ORDER BY folder" rsRecordSet2.Close set rsRecordSet2 = nothing Set rsRecordSet2 = Server.CreateObject("ADODB.RecordSet") rsRecordSet2.CursorLocation = adUseClient rsRecordSet2.Open strSQL2, dbConnection2, 1, 1 Set rsRecordSet2.ActiveConnection = Nothing if not rsRecordSet2.EOF then if rsRecordSet2("folder")*1 = 1 then stats_messenger_new_1 = rsRecordSet2("rcount") rsRecordSet2.movenext if not rsRecordSet2.EOF then stats_messenger_new_4 = rsRecordSet2("rcount") else stats_messenger_new_4 = 0*1 end if else stats_messenger_new_1 = 0*1 stats_messenger_new_4 = rsRecordSet2("rcount") end if else stats_messenger_new_1 = 0*1 stats_messenger_new_4 = 0*1 end if
strSQL2 = "SELECT folder, Count(folder) as rcount FROM messenger_messages WHERE [to] = '"&membername&"' AND ([read] = 0 OR [read] = -1) AND folder in (1,4) GROUP BY folder ORDER BY folder" rsRecordSet2.Close set rsRecordSet2 = nothing Set rsRecordSet2 = Server.CreateObject("ADODB.RecordSet") rsRecordSet2.CursorLocation = adUseClient rsRecordSet2.Open strSQL2, dbConnection2, 1, 1 Set rsRecordSet2.ActiveConnection = Nothing if not rsRecordSet2.EOF then if rsRecordSet2("folder")*1 = 1 then stats_messenger_unread_1 = rsRecordSet2("rcount") rsRecordSet2.movenext if not rsRecordSet2.EOF then stats_messenger_unread_4 = rsRecordSet2("rcount") else stats_messenger_unread_4 = 0*1 end if else stats_messenger_unread_1 = 0*1 stats_messenger_unread_4 = rsRecordSet2("rcount") end if else stats_messenger_unread_1 = 0*1 stats_messenger_unread_4 = 0*1 end if
en ide -> hvorfor ikke lade sql-serveren finde ud af om der er kommet nye beskeder til personen? Altså lave en stored procedure som finder nye beskeder - lægger dem delvist over i en helt ny tabel med brugerid, msgid, timestamp. denne stored procedure sætter du til at køre hvert minut via scheduleren. Dernæst laver du en lille aspside: strSQL = "SELECT * FROM NewMessages WITH(NOLOCK) where BrugerID = XXX" set res = conn.execute()strSQL) if not res.eof then while not res.eof response.write <a href=showmessage.asp?From=TmpTable&ID="&res("msgid")&">læs</a> res.movenext wend end if
siden kan du så inkludere der hvor den skal bruges og sætte den til at reloade hvert minut fx. (evt. ved at lægge den i en iframe). Jeg antager at siden hvor beskeder læses hedder showmessage.asp! På showmessage.asp selecter du fra den "store" message tabel - msgId er jo med i querystringen.... dernæst tilføjer du en lille stump kode som deleter den besked fra NewMessages som man har klikket på - ergo valgt at læse.
hmm... hvis jeg bare viste hvordan man arbejder med stored procedures :( Hele min messenger etc... virker fint, men på hver side skal der stå hvor mange meddelelser man har, og hver gang der er en ny meddelelse, afspilles en lyd... virker godt, men ikke optimalt :s
forresten - hvis du vil optimere performance i asp kan du jo oxo bruge getrows(). Et lille eks: strSQL = "select id, tekst, dato from mintabel order by date desc" set res = conn.execute(strSQL) if not res.eof then a = res.getrows() for i = 0 to ubound(a,2) response.write a(0,i) response.write a(1,i) response.write a(2,i) next else Response.write "EOF" end if
jeg bruger selv getrows en del - det er meget hurtigt ift. at løbe igennem et recordset
ok, det her har hjuplet meget :) tak for hjælpen!!!
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.