08. august 2001 - 23:07Der er
45 kommentarer og 3 løsninger
Søgetid, index mv
Jeg har en tabel i en db med en masse cd\'er i (ca. 170.000). Nu skal jeg til at rode lidt med index, for at få lidt fart på. Min tabel ser således ud:
CREATE TABLE cdbase ( cd_id int(11) DEFAULT \'0\' NOT NULL, kunstner varchar(250) NOT NULL, titel varchar(250) NOT NULL, status varchar(250) NOT NULL, year int(6) DEFAULT \'0\' NOT NULL, lagerantal int(11) DEFAULT \'0\' NOT NULL, medie varchar(20) NOT NULL, katalognr varchar(200) NOT NULL, selskab varchar(200) NOT NULL, CDantal varchar(20) NOT NULL, stregkode varchar(200) NOT NULL, pris float(16,2) DEFAULT \'0.00\' NOT NULL, genre varchar(200) NOT NULL, releasedato varchar(100) NOT NULL, PRIMARY KEY (cd_id) );
og mine søgninger vil typisk se således ud:
select * from cdbase where kunstner = \'bla\'
select * from cdbase where titel = \'bla\'
select * from cdbase where kunstner = \'bla\' AND titel = \'bla2\'
Meget simpelt indtil videre.
Jeg har følgende spm:
1. Hvordan skal jeg lave index på tabellen for at gøre søgningen hurtigere?
2. Det er en mysql 3.23.39, er der noget med transactions der speeder det lidt op, og er det noget man selv skal \"aktivere\"?
3. Kan man få returneret søgetiden, så jeg kan se om de ændringer jeg laver hjælper? evt gennem php?
Denne side indeholder artikler med forskellige perspektiver på Identity & Access Management i private og offentlige organisationer. Artiklerne behandler aktuelle IAM-emner og leveres af producenter, rådgivere og implementeringspartnere.
Bruger du LIKE hjælper indexer ingenting - tværtimod i de fleste tilfælde. Du skal kigge på noget der hedder noget i retning af FULLTEXTINDEX - det er noget alvion ved alt om - *g*
Som tidligere nævnt skal du lave indexes på de felter som du søger på. ud fra ovenstående vil det sige Kunstner og Titel.
Der er dog, som nævnt lige en detalje ved Like som det er værd at være opmærksom på.
Hvis søgninger med Like starter med % bruges indexet ikke. Hvis du derimod har den første del fast, bruges indexet alligevel.
Eksempel på det første er select * from cdbase where kunstner like \'%Kim%\' og på det sidste: select * from cdbase where kunstner like \'Kim%\'
Hvis du har konsol adgang til serveren vil jeg anbefale at lege lidt med \"mysql\" og fyre nogle statements af - så får du altid at vide hvor lang tid hver kørsel tager.
MHT. FULLTEXTINDEX så kan jeg ikke umiddelbart se hvordan det kan hjælpe her... Det kan bruges til søgninger efter ord/tokens. - men det er næppe relevant i forbindelse med din CD database.
Jamen dog er der ligefrem folk herinde der sidder og venter på mig? Jeg er beæret :-)
http://www.eksperten.dk/spm/81387 skulle besvare hvad i gerne vil vide om FULLTEXT indeks. Hvis det afføder nogle spørgsmål, så sig til herinde, så skal jeg svare så godt jeg kan
Og de andre spørgsmål:
2) Ja du kan godt bruge transactions, og nej de speeder *ikke* tingene op, hvis de endelig gør noget, så sætter de farten ned.
3) MySQL funktionerne i PHP kan ikke direkte fortælle dig hvor lang tid en query har taget, men det kan du jo selv måle således:
mukke -> FULLTEXT indeks er i den grad relevant for spiri\'s søgning. Hvis spiri skulle søge på om kunstnernavn indeholder et bestemt ord eller om titlen indeholder dette ord med LIKE, kan MySQL ikke bruge noget indeks. Det betyder at tabellen skal løbes igennem fra enden til anden.
Et FULLTEXT indeks vil derimod kunne indsætte ordene fra såvel titel, kunstnernavn, selskab og genre og give dig en meget fleksibel søgning.
Søger du f.eks. på \"love blues\" får du alle de cd\'er, hvor blot et af de to ord indgår i blot et af de ovenstående tekstfelter. Samtidig vægtes dit søgeresultat, således at de records der indeholder begge ord prioriteres bedst samt hvor mange gange ordene indgår.
Måske burde jeg ikke brokke mig, da en søgning på f.eks kunstner like metallica tager 1.40 sec.
Det er vel acceptabelt. (for én bruger)
Jeg prøver lige at fedte lidt rund med de forsk. forslag.
Nu lige til et rookie spørgsmål:
Hvordan ser det ud når der nu kommer en hel bunker brugere på samme tid? Vil indexeringen da hjælpe eller har det intet med hvor mange der tæsker løs i databasen at gøre?
Husk lige at svar, så jeg kan få delt nogen point ud:)
Alvion: ja,. men hvad nu hvis jeg skal søge efter noget af nana mouscori?
jeg er temmeligen i tvivl om hvordan det staves, ergo skriver jeg kun en del af ordet/navnet:
mous
og håber det er nok.
Som jeg forstår MATCH vil jeg IKKE få nogle resultater ud af dette. Hvis det stadig virker skal jeg gerne trække mine ord i mig igen. :) (Og jeg indrømmer gerne at jeg aldrig har brugt denne teknik så det er da ikke utænkeligt at jeg tager fejl :)
Senere skal jeg ha\' koblet en tabel på indeholdende hvilke numre der ligger på cd\'erne
den kunne se således ud: CREATE TABLE cdtracks ( trackid int(20) NOT NULL auto_increment, cd_id int(7) DEFAULT \'0\' NOT NULL, track varchar(150) NOT NULL, time varchar(7) NOT NULL, PRIMARY KEY (trackid) );
...hvor cd_id er fremmednøglen.
Hvis jeg så skal søge på et nummer for at finde de cd\'er indeholdene pågældende nummer, hvordan ser det så ud med index?
FULLTEXT indeks kan vist nok (jeg er lidt på gyngende grund her) fange ordet, hvis du har skrevet den første del. Dvs. har jeg nu navnet \"carsten\" i mit index, vil en MATCH finde det med disse \"søgeord\":
Testet og jeg havde desværre ikke ret. Den finder kun hele ord. Det andet jeg taler om bliver - ifølge dokumentationen - implementeret i MySQL version 4.0.
f.eks: CREATE FULLTEXT INDEX ft_1 ON cdbase (kunstner); CREATE FULLTEXT INDEX ft_2 ON cdbase (titel); CREATE FULLTEXT INDEX ft_3 ON cdbase (kunstner,titel);
da jeg for fejl hvis jeg søger således: SELECT * FROM cdbase WHERE MATCH(kunstner) AGAINST (\'søgeord\');
på et index jeg har lavet der hedder: CREATE FULLTEXT INDEX ft ON cdbase (kunstner,titel);
...man skulle gerne kunne søge på kunstner, eller titel eller begge dele.
tjae.. jeg er ikke helt klar over hvor meget det giver at have et kombineret index - det du skal lave vil som minimum være et indeks på hver af de to felter... om den tredie skal med kan du jo eksperimentere lidt med via mysql klienten. (prøv nogle opslag med og uden det tredie, kombinerede index.
Din MATCH sætning skal altid indeholde de samme feltnavne som en af dine FULLTEXT indeks. MySQL finder så selv ud af hvilken af dine indeks den skal bruge.
mukke -> Det et kombineret indeks giver er muligheden for at lave \"fritekstsøgning\" på hele records på tværs af felterne. Det kan være meget brugbart.
Kan man forøvrigt, på en eller anden må søge på en streng.
F. eks \"ray of light\".
sådan som jeg har forstået dokumentationen vil den i ovenstående tilfælde smide både \"ray\" og \"of\" væk, med mindre man recompiler mysql, til at acceptere ord mindre end 3 karakterer.
...men det er vist ikke nogen god idé. Men som sagt kan man få den til at opfatte \"ray of light\" som ét ord?
Ellers er det jo lige før man ikke kan bruge dette ellers fantastisk hurtige index-værk.
Det samme gør sig desværre gældende her som ved dele af ord: Hvis det skal være muligt (og det vil jeg tro det skal) så kan du ikke bruge fulltext indexes :(
Ville det være for langt at oprette 2 attributter mere f.eks kunstner_seek og title_seek og derefter løbe alle posterne igennem, for så at indsætte \"ray of light\" som ray_of_light i de nye attributter?
...eller ville det være for meget et \"spagettihack\"?
ps. selvfølgelig skulle man også tilpasse det i php så underscores bliver indsat mellem orderne.
Nu skal jeg forøvrigt nok snart holde min bøtte i dette spørgsmål!
Vil du, når man søger efter noget, tilføje søgestrengen til alle poster? Hvad skulle det gøre godt for?
Vil du i forbindelse med indsætning af dataene samtidig lave ekstra felter med hele teksten uden mellemrum men _ i stedet? I så fald vil MATCH bare opfatte hele titlen henholdsvis kunstneren som et ord/token, og du vil stadigvæk ikke have opnået noget.
Jeg har også et lille spørgsmål vedr. dette fantastisk fulltextindex ting. Jeg har en database med en masse navne i. det fungerer fint med fulltext, men sammensatte navne får jeg ikke med f.eks. navn: Bente Knudsen-Petersen Jeg får hverken posten frem ved at søge \'knudsen\', \'pedersen\' eller \'knudsen-pedersen\'. Hvad skal jeg så søge på?
MySQL definerer ord til ordlisten som værende \"sammensætninger af tegn imellem whitespaces\". Jeg ved ikke om bindestreg \"-\" tæller som et whitespace, men ellers kan du jo selv tilføje det i sourcekoden. :-)
Det må jeg gøre. Men jeg kan stadig ikke forstå at det fulde efternavn ikke giver noget udtræk. Men det må der stå om et eller andet sted :-) Takker...
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.