webForumDet fria alternativet

Snabba upp SQL/Loop?

22 svar · 1 164 visningar · startad av oskars

oskarsMedlem sedan nov. 20051 317 inlägg
#1

Tjenare på er!

Jag har följande kod:

<%
	Set RecSet2 = Server.CreateObject("ADODB.Recordset")
	SQL2 = "Select ID,Projekt,sID,Namn,Efternamn,Adress FROM Adresser WHERE Projekt = "& Session("P") &" AND sID = '"& Session("userID") &"' AND CD = 0 AND TOrder = 0 AND AB = 0 ORDER BY "& Request.Cookies("sort") &" asc"
	RecSet2.Open SQL2, Connect, 1, 2
	
	page = 1
	
	Do Until RecSet2.EOF
	
	
	If Page = 1 Then 
	
	%>
	
	<option style="color:#CCC;">Sortering: Namn</option>
	<option></option>
	
	<% End If %>
	
	<option <%= style %> value=""><%=announce%> <%=Page%>: <%=lcase(RecSet2("Efternamn"))%>: <%=lcase(RecSet2("Adress"))%></option>
	
	<%
	
	RecSet2.MoveNext
	page = page + 1
	Loop
%>

Men jag tycker den tar för jävla lång tid på sig att köra klart... även om den bara loopar igenom ungefär 30st poster.

Säg att sidan tar 1000ms att ladda när jag har den loopen aktiv, så minskar det till 600ms om jag tar bort den.

Hur kan jag komprimera och optimera den måntro? Har försökt så gott jag kan, men den tuggar ändå massa MS :D

Mvh
Oskar

spangoMedlem sedan juni 20008 205 inlägg
#2

För det första, har du några index i tabellen?

För det andra, du öppnar för SQL-injektion, eftersom cookies kommer direkt från klienten.

oskarsMedlem sedan nov. 20051 317 inlägg
#3

spango skrev:

För det första, har du några index i tabellen?

Njaeh, vad är det? :o

spango skrev:

För det andra, du öppnar för SQL-injektion, eftersom cookies kommer direkt från klienten.

Jag vet... Det är inte så viktigt i just det här fallet :) Tack för upplysningen iaf!

spangoMedlem sedan juni 20008 205 inlägg
#4

oskars skrev:

Njaeh, vad är det? :o

Index är sånt man ska ha på kolumner man söker på ;) Utan index kan man alltid räkna med ett en sökning på en icke-trivial datamängd går skitlångsamt.
http://en.wikipedia.org/wiki/Database_index

oskars skrev:

Jag vet... Det är inte så viktigt i just det här fallet :) Tack för upplysningen iaf!

Det är alltid viktigt. Faktiskt. Alltid. Det är bara sopor som ignorerar sånt. Det tar dig max två minuter - antagligen mindre - att ordna en koll som gör att ingen droppar en massa tabeller. Det finns ingen anledning att inte göra det.

oskarsMedlem sedan nov. 20051 317 inlägg
#5

spango skrev:

Index är sånt man ska ha på kolumner man söker på ;) Utan index kan man alltid räkna med ett en sökning på en icke-trivial datamängd går skitlångsamt.
http://en.wikipedia.org/wiki/Database_index

Hm, okej... ska jag hålla på med det där reverse() och så?

spango skrev:

Det är alltid viktigt. Faktiskt. Alltid. Det är bara sopor som ignorerar sånt. Det tar dig max två minuter - antagligen mindre - att ordna en koll som gör att ingen droppar en massa tabeller. Det finns ingen anledning att inte göra det.

:( Och jag är ju ingen sopa. Ska bättra mig!

spangoMedlem sedan juni 20008 205 inlägg
#6

oskars skrev:

Hm, okej... ska jag hålla på med det där reverse() och så?

Bara om du gör wildcardsökningar på slutet av strängar, vilket du inte gör i din fråga. Inser nu att wikipediasidan faktiskt var rätt keff. Där får man för att man är lat.

Index är (oftast) en sorterad datastruktur, t.ex. ett träd, vilket gör att man kan göra sökningar larvigt mycket snabbare. En passande jämförelse är ett vanligt, hederligt uppslagsverk i bokform - där är artiklarna "indexerade" på uppslagsordet, så du vet att uppslagsordet "ablativ" ligger mellan uppslagsorden "Aachen" och "ackord". Om uppslagsorden istället låg huller om buller har du ungefär samma situation som databasen har när den får uppgiften att söka på oindexerade kolumner.

Exakt vad man ska indexera beror på hur databasen är uppbyggd och hur den används. I ditt fall skulle jag nog gissa att adresser.projekt eller adresser.sID skulle vara lämpliga kandidater (eller ett kombinerat index på båda kolumnerna - en sökning kan bara använda ett index per tabell, så har man ett index på vardera kolumn kommer fortfarande bara ett index användas).

oskars skrev:

:( Och jag är ju ingen sopa. Ska bättra mig!

Precis, så ska det låta :)

oskarsMedlem sedan nov. 20051 317 inlägg
#7

Aaah... bra förklaring... tror jag :) Känns bra iaf!

Kan man säga att det borde gå snabbare om jag gör så här:

SELECT minTabell.ID, minTabell.Namn, minTabell.Efternamn WHERE Projekt = 1

spango skrev:

Precis, så ska det låta :)

:bire :stud

spangoMedlem sedan juni 20008 205 inlägg
#8

oskars skrev:

Kan man säga att det borde gå snabbare om jag gör så här:

SELECT minTabell.ID, minTabell.Namn, minTabell.Efternamn WHERE Projekt = 1

Ehm, inte speciellt, men den där frågan gör ju inte ens samma sak?

oskarsMedlem sedan nov. 20051 317 inlägg
#9

Tänkte förkorta den lite... misslyckades... Så här menar jag:

SQL2 = "Select adresser.ID,adresser.Projekt,adresser.sID,adresser.Namn,adresser.Efternamn,adresser.Adress FROM Adresser WHERE Projekt = "& Session("P") &" AND sID = '"& Session("userID") &"' AND CD = 0 AND TOrder = 0 AND AB = 0 ORDER BY "& Request.Cookies("sort") &" asc"

Har jag fattat allt fel?

spangoMedlem sedan juni 20008 205 inlägg
#10

Du menar om du kvalificerar namnen (adresser.id) istället? Det lär inte göra någon större skillnad.

oskarsMedlem sedan nov. 20051 317 inlägg
#11

spango skrev:

Exakt vad man ska indexera beror på hur databasen är uppbyggd och hur den används. I ditt fall skulle jag nog gissa att adresser.projekt eller adresser.sID skulle vara lämpliga kandidater (eller ett kombinerat index på båda kolumnerna - en sökning kan bara använda ett index per tabell, så har man ett index på vardera kolumn kommer fortfarande bara ett index användas).

Trodde det var det du menade :r

spangoMedlem sedan juni 20008 205 inlägg
#12

Nej, jag menade att du skulle lägga in index på de kolumnerna ;) Det är en engångsgrej som du gör med ett CREATE INDEX-kommando eller nåt drag'n'drool-verktyg. Jag hänvisar till manualen för din DBMS...

oskarsMedlem sedan nov. 20051 317 inlägg
#13

Åfan... det låter ju... hm... bra...

Ska jag tänka så här då:

Jag sätter INDEX på dom kolumnerna som jag ofta söker efter?
T.ex adresser.ID,adresser.Projekt,adresser.sID,adresser.Namn,adresser.Efternamn,adresser.Adress

Kommer detta påverka några andra sökningar än just dessa? Eller är det här bara en liten optimering som görs...

EDIT: Det är 37000st poster i denna databasen (MySQL).

spangoMedlem sedan juni 20008 205 inlägg
#14

oskars skrev:

Jag sätter INDEX på dom kolumnerna som jag ofta söker efter?
T.ex adresser.ID, adresser.Projekt,adresser.sID, adresser.Namn,adresser. Efternamn, adresser.Adress

Ja, precis så. Som sagt, tänk dig en sorterad lista. Sen ska man vara medveten om att inserts och updates av indexerade kolumner blir något långsammare av index (eftersom man inte bara måste uppdatera tabellen utan också indexen) och att index använder upp en del minne, så man ska inte indexera i onödan (aldrig får det vara enkelt ;) ).

De bieffekter index kan ha är som sagt långsammare inserts/updates samt ökad minnesförbrukning, men de bör inte påverka selects på annat sätt än att de blir snabbare. Teoretiskt kan också ordningen på raderna ändras vid vissa selects (men ORDER BY funkar förstås fortfarande som det ska).

oskarsMedlem sedan nov. 20051 317 inlägg
#15

Okej, tack för förklaringarna...

CREATE INDEX myTable_INDEX on myTable (Namn, Efternamn, Adress)

Om jag kör den här koden så blir sökningarna snabbare... när då? När jag bara söker på Namn & Efternamn i en fråga, eller även när jag söker på t.ex Namn, Efternamn och Ort?

Blir det en avsevärd skillnad på minnesförbrukningen?

spangoMedlem sedan juni 20008 205 inlägg
#16

Om du gör ett index som ovan får databasen en "lista" över alla poster i tabellen sorterad efter i första hand Namn, sedan Efternamn, och sist Adress. Så här:

Namn | Efternamn   | Adress
-----+-------------+---------
Ada  | Bengtsson   | B-vägen
Ada  | Ögren       | C-vägen
Aud  | Torstensson | A-vägen
Ida  | Bengtsson   | B-vägen
Per  | Andersson   | A-vägen
Per  | Andersson   | B-vägen

Söker du på namn kan du alltså utnyttja indexet. Söker du på namn och efternamn kan du utnyttja indexet. Söker du på namn, efternamn och adress kan du utnyttja indexet.

Gör du en fråga som SELECT * FROM adress WHERE Namn = 'Ada' AND ort = 'Göteborg' kommer indexet utnyttjas delvis, den kommer kunna använda det för att leta upp alla Ada, men sen måste den gå igenom alla de raderna och kolla var och en huruvida ort = 'Göteborg' eller inte. Finns det skitmånga Ada i Göteborg kan det bli jobbigt, men den första indexsökningen kan reducera antalet poster databasen måste kolla igenom ganska rejält, så det kan man antagligen leva med.

MySQL har en ganska bra funktion som heter EXPLAIN som visar hur den utför frågor. Läs på i manualen och experimentera lite med olika index för att se hur olika frågor optimeras.

Hur mycket minne som används beror på nyckelns storlek, och hur databasen är implementerad. Du kan ju kolla källkoden till MySQL för att få en uppfattning ;)

oskarsMedlem sedan nov. 20051 317 inlägg
#17

Okej, då förstår jag lite bättre.

Är det smart att typ leta upp dom frågorna som används mest och skapa index efter dom?

spangoMedlem sedan juni 20008 205 inlägg
#18

Ja, precis.

oskarsMedlem sedan nov. 20051 317 inlägg
#19

Tjenare på er!

Börjar få ordning på INDEX nu =) Det går snabbare vid mina SQL-frågor nu!

Men det finns ilte saker jag funderar på ...

jag har lite inställningar som jag kan göra för mina INDEX:
Primary
Fulltext (detta antar jag fungera på det viset att man får välja hur många tecken den ska indexera på? AFTONBLADET kan man t.ex göra till AFTON (5 tecken) osv.?)
Unique

Är det dumt att lägga in många (låt oss säga 10st) fält i ett INDEX? Ska jag hellre göra flera små INDEX?

spangoMedlem sedan juni 20008 205 inlägg
#20

Dokumentationen är bra :) http://dev.mysql.com/doc/refman/4.1/en/create-index.html

Primary betyder att fältet blir primärnyckel, dvs den måste vara unik och icke-null.

Unique betyder att fältet antingen måste vara unikt eller null (fler rader får ha samma värde på en kolumn med unikt index om och endast om värdet är null).

Fulltext betyder att du skapar ett fulltextindex, dvs att du kan söka på godtyckliga termer på godtycklig placering i en text. http://dev.mysql.com/doc/refman/4.1/en/fulltext-search.html

Vad man ska indexera beror helt och hållet på hur datan och frågorna ser ut. Gör du index som täcker fler fält blir sökningar på samtliga dessa kolumner snabbare, men sökningar på bara ett eller några få fält kommer sannolikt gå långsammare.

133 ms totalt · 3 externa anrop · v20260731065814-full.30151723
131 ms — hämta forumlista (db)
0 ms — hämta statistik (cache)
129 ms — hämta tråd, inlägg och bilagor (db)