Avatar billede mikkelk Nybegynder
14. maj 2003 - 12:56 Der er 17 kommentarer og
2 løsninger

Hvordan med index i tabeller?

Jeg kunne godt tænke mig at vide hvornår man bør oprette index's i sine tabeller, samt hvordan de skal oprettes, hvilke felter man kan oprette dem på og hvorfor?
Gerne et rimeligt fyldestgørende, men let tilgængeligt svar...tak :-)
Avatar billede fsconsult.dk Nybegynder
14. maj 2003 - 13:06 #1
Det indlysende svar: når der er brug for dem :-)

Selv udnytter jeg MySQL feature med at logge langsomme queries, og optimerer de bruger forespørgsler der tager 1 sekund eller mere.

Du skal lave index på de felter som dine tunge forespørgsler søger på, sortererer på, samt af og til de felter der selectes (for at modvirke en table scan).

For en given query kan du sætte EXPLAIN foran, hvilket vil få MySQL til at fortælle dig hvilke index den har tænkt sig at benytte, så du kan tilpasse dine index så den vælger dem (og undgår table scans).

Kig på www.mysql.com/doc for dokumentation af syntaks til oprettelse af index, eller benyt phpMyAdmin eller lign. værktøj til at administrere dine databaser med :)
Avatar billede ahv Nybegynder
14. maj 2003 - 13:06 #2
Avatar billede ahv Nybegynder
14. maj 2003 - 13:08 #3
Et lille eksempel som kan give dig et indblik i hvor meget hurtigere det vil gå hvis du indeksere rigtigt;

Et eksempel kunne være, en database med tabellen "test".
Heri er der 1.000.000 rækker som har et id og et datetime felt.
Lad os sige der er 11 ud af dissse 1.000.000 poster som er ældre end 2 timer og dem vil vi trække ud.
Dette vil tage ca. 0.260246992111
Går vi nu ind og indeksere datetime (som vi jo søger på) i tabellen, og prøver igen, ja så får du en tid der siger:
ca. 0.00083601474762
Altså er hastigheden steget ca. 300 gange.
Avatar billede mikkelk Nybegynder
14. maj 2003 - 13:13 #4
Så må mit spørgsmål være... hvorfor ikke bare lave index på alle felterne?
Og...er det en god ide at lave index på id-feltet?
Avatar billede fsconsult.dk Nybegynder
14. maj 2003 - 13:16 #5
Dit id felt vil typisk være en primær nøgle, og det er automatisk et unikt index samtidigt.

Man laver sjældent ét indeks på samtlige felter, da rækkefølgende af de enkelte felter i indekset er afgørende for om MySQL kan benytte det indeks i den enkelte query.
Avatar billede mikkelk Nybegynder
14. maj 2003 - 13:19 #6
Hvornår laver man så index? på hvilke felter?
Avatar billede fsconsult.dk Nybegynder
14. maj 2003 - 13:19 #7
De felter der indgår i dit WHERE statement med = vil typisk være gode felter at have først i et index, og hvis du har et felt du søger på med > eller < vil det ofte med fordel kunne placeres sidst i indekset. Det er dog svært at sige noget generelt da det afhænger af det enkelte query.

Mit bedste bud er at benytte SLOW_QUERIES og optimere faktiske problemer istedet for at gætte sig frem til evt. flaskehalse.

Dog er det (næsten) altid en god ide at have indeks på fremmednøgle (som er primærnøgler i tabeller du joiner med)
Avatar billede websmith Nybegynder
14. maj 2003 - 13:20 #8
Hvis man har uanede mængder at plad på sin server, og det samtidig er et stort svin af en server, så kan man godt indexere alle sine felter, men man skal huske på at for hvert index man putter på en tabel, så skal serveren opdatere index når der bliver slettet eller indsæt records, og derfor vil et index sløve sletninger og indsætninger/updates gevaldigt meget.

Man skal stort set kun oprette idex på felter som brugt i select statements i følgende:

Where xxx='yyy' (lav index på xxx)
Order by ppp (lav index på ppp)
where xxx='yyy' and zzz='yyy' (lav index på xxx+zzz, dvs index tofields(xxx,zzz)

mvh
Avatar billede mikkelk Nybegynder
14. maj 2003 - 13:24 #9
ahh...nu begynder jeg at forstå...jeg havde ikke lige fattet at man kunne lave indeks på flere felter på én gang...
Avatar billede mikkelk Nybegynder
14. maj 2003 - 13:30 #10
Ok...så kunne jeg godt tænke mig at vide...
Hvis jeg nu har følgende to statements:

where xxx='yyy' and zzz='yyy'
og
where xxx='yyy' and zzz='yyy' and qqq='fff'

Skal jeg så lave to indeks'(på xxx+zzz og xxx+zzz+qqq) eller... blot på xxx+zzz+qqq???
Avatar billede fsconsult.dk Nybegynder
14. maj 2003 - 13:30 #11
samt

where xxx='yyy' and zzz='yyy' Order by ppp (lav index på xxx+zzz+ppp, dvs index tofields(xxx,zzz,ppp)
Avatar billede websmith Nybegynder
14. maj 2003 - 13:33 #12
Jo hvis det findes et index som matcher de krav der er til en query, så bruger mySQL det, ellers vil den bruge de index som ellers matcher, dvs.

Hvis din select er:

"select * from tabel where x=y and z=y"

så vil mySQL bruge index som følger,

index twofields(x,z)
index onefielda x, index onefieldb z

Hvis der ikke er nogen index overhovedet, så er det at det bliver langsomt, da den skal hente alle records i tabellen og matche dem med din selec statement.

Når du laver index med flere felter, så skal du også huske at oprette dem med felterne i den rækkefølge du bruger i din select statement.

Dvs hvis
"select * from a where x=y and z=y"

Så skal indexet være index twofields(x,z), ikke index twofields(z,y)

mvh
Avatar billede fsconsult.dk Nybegynder
14. maj 2003 - 13:33 #13
mikkelk> det kommer lidt an på dine data.

index på xxx og zzz vil i mange tilfælde være tilstrækkeligt medmindre der er mange qqq for hver xxx,yyy kombination.

det er for det meste en fordel at have index med få felter, da de så er hurtigere at løbe igennem

men prøv at oprette begge index, og kør EXPLAIN på begge dine forespørgsler og se hvad MySQL vælger at benytte
Avatar billede mikkelk Nybegynder
14. maj 2003 - 13:34 #14
vil det sige at jeg i det nævnte eks. kan nøjes med xxx+zzz+qqq???
Avatar billede websmith Nybegynder
14. maj 2003 - 13:34 #15
Jeg er ikke sikker når du bruger to forskellige selects, men jeg tror at det er nok med dit index med alle tre felter, men prøv at læse lidt i dokumentationen på www.mysql.com, den er faktisk rigtig god :)
Avatar billede fsconsult.dk Nybegynder
14. maj 2003 - 13:38 #16
jeg ville satse på xxx+zzz men teste det med EXPLAIN (altid en god ide)
Avatar billede mikkelk Nybegynder
14. maj 2003 - 13:41 #17
Og så bliver du jo nødt til at forklare lidt grundigere hvordan jeg tester det med EXPLAIN?
Avatar billede websmith Nybegynder
14. maj 2003 - 13:43 #18
use database
explain select * from tabel where x=y and z=y
Avatar billede mikkelk Nybegynder
14. maj 2003 - 15:17 #19
Mange tak for hjælpen...
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
Computerworld tilbyder specialiserede kurser i database-management

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