04. maj 2008 - 12:34Der er
15 kommentarer og 2 løsninger
Full-text index på multi column unique key
Bruger mssql 2005
Jeg prøver at lave et full text index ... men det kræver en single single column unique index, som jeg ikke har, fordi jeg importere data fra flere servere, og har selv delt dem op med et "Server ID" så deres rows bliver unique. Det er et så multi column unique index.
Hvordan kan jeg så lave et full text index ? Jeg skal søge i 3 tables efter samme string, og efter min overbevisning, burde det være hurtigere med "full text index" end med "LIKE" ... da den pt tager ca. 110 ms ... hvilket er lidt i overkanten.
Kan det laves med et view ? hvis, hvordan så ? Er der nogen der har nogen tips eller triks, jeg kan bruge for at løse mit program .... ?
Det skal siges at det drejer sig om ca. 10 mill rows ... fordelt (6/3/1) på de 3 tables ... derfor måske full text index var en god ide ....
Har du evt. mulighed for at tilføje en ekstra kolonne til din tabel, som "bare" er en IDENTITY (1,1)? Så kan du lave det nødvendige index på den kolonne, og behøver ikke bekymre dig om at lave dine eksisterende ting om.
har jeg ... men kontra ekstra plads det tager, (index størrelse, selve key'n og andre ting der måtte komme ) ... kunne selvf være en ide ... og nok egenligt den bedste efter jeg har tænkte lidt over det ...
Men er der nogen dybere grund til at sådan et full text index ikke kan tage en multi column key ... det virker for mig som en helt normal ting, der må da være flere end mig som falder i den her fælde, og må oprette flere keys bare for at kunne lave "full text" ...
Næste problem kommer jo så når jeg vil søge i 3 tables ... det kan jo igen så ikke laves på andre måder end med 3 quries, havde håbet på at lave et view, men det ville jo nok alligevel i sidste end give sammen resultat ...
hmmm, jeg vil prøve at se lidt mere på pros/cons ved det ...
Jeg takker for input, men vil lige lade det stå åbent lidt tid endnu, kan jo ske at der kommer en med det perfekte guldkorn jeg lige mangler :-)
Ja hvis du skal have fulltext search på et view (jeg er ikke sikker på man kan, men jeg vil tro det), så har man desværre stadig problemer med at der skal være dette single column unique index. Så hvis du skal lave et view som samler dine 3 tabeller, så skal du have oprettet et clustered index på dette view - hvilket betyder at du har al data liggende dobbelt.
Måske andre har bedre idéer, men jeg er bange for at du nok er nødt til at tilføje en kolonne til hver af dine 3 tabeller, som du kan bygge et unikt index på, og så lave fulltext på alle 3 tabeller hver især.
Næsten problem, søgning ... den kan ikke søge på suffix ... tænke tænkte ... ikke store data mængder ... ca. varchar felter af ca. 5 til 20 vil jeg tro ...
Folk skriver man kan lave endnu en column, hvor man så kan søge på ordet hvor det er stavet modsat ... men er det den rigtige vej ? eller er der kommet en mulighed som jeg har misset i al min google søgning.
Der sker kun opdatering i de tables 1 gang i døgnet ... så det kunne måske laves noget med trigger på DB'en ... så et felt bliver indsat eller opdateret ... og derpå lave den reverse order af ordet ...
Skal lige høre om noget... Du taler om en composite key right? Lav et clustered unique index på dine nøglefelter, i dit tilfælde serverid og den row du taler om. Hvad siger den så?
Du har ret sjang, jeg ville nok sikkert også tilføje en id-column så :)
buzzzz-> du kunne jo, hvis du ikke allerede gør det, anvende en tinyint til din serverid.
Nu har jeg godt nok ikke selv prøvet det, men jeg ved da at SQL2005 understøtter FTI på over linked servers, så måske det var noget? Det kræver måske at alle serverne er SQL2005, men man kunne jo kigge på det :)
Linked Servers er blot et koncept sådan at man kan kommunikere med flere servere eks.vis over netværk f.eks
select * from [192.168.1.1].MyDatabase.dbo.Table union select * from [192.168.1.10].MyDatabase.dbo.Table
Så får du samtlige rækker som optræder i Table på server 1.1 og 1.10 --- For at bruge FTI på linked servers skal der eksistere et FTI på tabellen på den respektive server. Når det så er oprettet....
Så kan du evt. sætte en note ind i din union sådan her: select 'a' as server, * from [192.168.1.1].MyDatabase.dbo.Table union select 'b', * from [192.168.1.10].MyDatabase.dbo.Table
SÅ kan du se i dit resultset på hvilken server / tabel strengen findes på ;-) --
Du kan godt bruge FTI til at søge på dele, brug en contains og en asterix ifb. med søgeordet: select * from MyTable where CONTAINS(*, '"searchword*"')
Husk at sætte søgeordet i "" :)
En anden god ting du også kan med FTI er jo at lave en INFLECTIONAL search, så eks.vis vil en søgning efter "easy" både give dig resultater med "... easy...", men også med formen "... easier..."
Ja, men det er primært bynavne,username og gruppenavne som folk kan finde på, så jeg kan ikke bruge INFLECTIONAL til så meget ... der kan også nemt være flere forskellige sprog.
Hvis du selv prøver at søge i et FTI ... også søger efter "uper" ... så finder den ikke supermand hvis det står som et ord, det mit problem består i ... eller, ved ikke helt om det er nødvendig at den skal kunne det, men der hele mit spørgsmål startede .. og det lader ikke til at der er nogen løsning på det.
Ahhh, på den måde med linked servers, kunne man jo smide ting som ikke blive brugt så tit og kræver meget CPU kræft ... og så for at lette præsset på selve, men lyder mere som noget der bliver brugt til meget store applicationer, da det vil give en del ekstra overhead at holde styr på ... :-)
Ellers skulle man lave sådan en lille fidus med at dele ordet gradvist, når det nu er bynavne er det jo rimeligt overkommeligt hmmm.. se her
Eks.vis "Valby" kunne jo skrive som "V alby Va lby Val by Valb y Valby" og så lave en FTI på den :) På den måde vil den finde Valby når der blev søgt efter 'alby' eller 'alb'
Sad og læste lidt om det, men synes ikke rigtigt lige jeg kunne se nogle sønderlige forbedringer fra 2005 til 2008.
Normalt laver man jo som du selv lige kort var inde på, en reverse af sætningen eller ordet. Dvs. Valby bliver til 'yblaV' , det tages så også med i FTI og når du så kommer med en søgning, søges der både på korrekt vis "Hvalby" men så vendes user inputtet om - og på den måde får man også et hit selvom brugeren måske starter Valby med H *S* da man jo både søger efter Hvalby (som ikke hitter) men samtidigt også reversen 'yblavH' og den hitter med 'yblaV'
Det er sådan den normale teknik at lave en tilnærmet wildcard ;) skide besværligt haha...
Ellers skal man ud i noget ala soundex, men det bliver hurtigt noget underligt knald, men måske det kan inspirere.
At søge baglens, brugte jeg en trigger til at oprette det omvendte ord, da jeg lavede insert/update ... men stadig træls måde ... jeg må overleve med det performance hit det giver at bruge wildcards i begge ender.
ja, giver heller ikke noget her, da folk selv opfinder ord etc. så soundex tvivler jeg på ville være brugbart.
Jeg må overleve med det jeg allerede gør ...
Jeg vil dog stadig smide 10 point til sjang og resten til janus, da jeg synes i skal have lidt for jeres tid her :-)
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.