Avatar billede supermand69 Nybegynder
03. september 2005 - 10:02 Der er 4 kommentarer og
1 løsning

index på varchar felt

Hey

Vil det overhovedet have nogen som helst fordel at smide et index på et varchar eller char felt, andet end databasen bliver større? For den indekserer vel kun feltet alfabetisk, så hvis man søger efter en string som kunne være et hvilket som helst sted i feltet (eks. midt i feltet eller i slutningen) vil det vel ikke have nogen betydning om der et index derpå?
Avatar billede kjulius Novice
03. september 2005 - 12:33 #1
Det kommer skam an på hvad du vil bruge dit varchar felt til. I sig selv er det ikke en dårlig idé at sætte et index på et varchar felt.

Ud fra dit spørgsmål har jeg dog den fået den grimme tanke, at du mener et stort felt hvor du vil putte alskens ustrukturerede informationer ind i. A definite No, No!

Det er altid en dårlig idé at opbygge sin database med store felter, som indeholder mange forskellige oplysninger, som man så er nødt til at søge på ved at bruge en LIKE '%etellerandet%'. Så vidt det overhovedet er muligt bør man af performancehensyn bruge et felt pr. oplysning, og så tage med i købet, at man er nødt til at opbygge en større forespørgsel. Det betyder ikke nødvendigvis, at man helt skal undgå LIKE funktionen, for hvis man kan nøjes med at bruge LIKE 'etellerandet%', så kan databasen stadig udnytte et index.

Med andre ord, undgå så vidt muligt situationen, hvor du putter en masse søgeord i et stort felt, med f.eks. komma imellem.
Opbyg hellere en selvstændig tabel med søgeordene, som du så joiner med den tabel du søger i:

SELECT * FROM oplysningstabel WHERE søgefelt LIKE '%søgekriterie1%' or søgefelt LIKE '%søgekriterie2%'

Ovenstående er et eksempel på dårligt opbygget database som ikke vil performe særligt godt, da den ikke kan udnytte indexer.

SELECT oplysningstabel.* FROM oplysningstabel INNER JOIN søgeordstabel ON oplysningstabel.linkfelt = søgeordstabel.linkfelt
WHERE søgeordstabel.søgefelt = 'søgekriterie1' or søgeordstabel.søgefelt = 'søgekriterie2'

Ovenstående er et eksempel på en databaseopbygning som vil performe godt og vil have stor gavn af et index.

Med en sådan opbygning kan du endog søge på en del af søgeordet og stadig have gavn af indexet (bare du holder dig til at søge på starten af søgeordet), f.eks.:

SELECT oplysningstabel.* FROM oplysningstabel INNER JOIN søgeordstabel ON oplysningstabel.linkfelt = søgeordstabel.linkfelt
WHERE søgeordstabel.søgefelt LIKE 'søgekriterie1%' or søgeordstabel.søgefelt LIKE 'søgekriterie2%'

ref.: MySQL Manualen, kapitel 7.4.5 How MySQL Uses Indexes
A B-tree index can be used for column comparisons in expressions that use the =, >, >=, <, <=, or BETWEEN operators. The index also can be used for LIKE comparisons if the argument to LIKE is a constant string that doesn't start with a wildcard character. For example, the following SELECT statements use indexes:

SELECT * FROM tbl_name WHERE key_col LIKE 'Patrick%';
SELECT * FROM tbl_name WHERE key_col LIKE 'Pat%_ck%';

In the first statement, only rows with 'Patrick' <= key_col < 'Patricl' are considered. In the second statement, only rows with 'Pat' <= key_col < 'Pau' are considered.

The following SELECT statements do not use indexes:

SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%';
SELECT * FROM tbl_name WHERE key_col LIKE other_col;

In the first statement, the LIKE value begins with a wildcard character. In the second statement, the LIKE value is not a constant.

MySQL 4.0 and up performs an additional LIKE optimization. If you use ... LIKE '%string%' and string is longer than three characters, MySQL uses the Turbo Boyer-Moore algorithm to initialize the pattern for the string and then use this pattern to perform the search quicker.


Alternativt kan du, hvis du insisterer på et stort felt med ustrukturerede data,  kigge på full-text search, som findes i nyere versioner af MySQL:
http://dev.mysql.com/doc/mysql/en/fulltext-search.html

Performancemæssigt vil det nok ligge mellem de to ovenstående hvor man benytter sig af alm. SQL syntax og tabeller.
Avatar billede supermand69 Nybegynder
05. september 2005 - 18:23 #2
Ja, i lige præcis dette her felt skal man bruge LIKE, men det er også det eneste felt man skal. Det er nemlig brugernavne som står i feltet :)

Ellers bruger jeg også JOIN som du forklarer i din kommentar, og jeg bruger så vidt muligt INT's i mine felter, som er nøgler til et array :)

Ud fra det du skriver vil jeg tro jeg ikke vil have noget som helst ud af at smide et index på mit "brugernavn"-felt? Korrekt? hehe...
Avatar billede kjulius Novice
05. september 2005 - 21:35 #3
Nej, ifølge dokumentationen bruger MySQL ikke et index, hvis man bruge LIKE til at søge i hele feltet.
Avatar billede kjulius Novice
05. september 2005 - 21:41 #4
For nu ikke at blive misforstået, må jeg hellere lige omformulere mit svar:

Ja, det er korrekt. Ifølge dokumentationen bruger MySQL ikke et index, hvis man bruger LIKE til at søge i hele feltet (altså LIKE '%etellerandet%').
Avatar billede supermand69 Nybegynder
06. september 2005 - 15:57 #5
ok.. tak, det var det svar jeg søgte ;)
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