Avatar billede Syska Mester
04. maj 2008 - 12:34 Der 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 ....

// ouT
Avatar billede HenrikSjang Nybegynder
04. maj 2008 - 15:03 #1
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.
Avatar billede Syska Mester
04. maj 2008 - 15:12 #2
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 :-)

// ouT
Avatar billede HenrikSjang Nybegynder
04. maj 2008 - 16:14 #3
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.
Avatar billede Syska Mester
04. maj 2008 - 18:36 #4
ja, det giver da en speedup på 5x ....

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 ...

// ouT

// ouT

//  oUT
Avatar billede Syska Mester
04. maj 2008 - 20:45 #5
Well ... ham som skrev det med at lave Reverse af ens sætning, og så søge igen ... det løser jo intet ved mig ...

Bliver sindsyg ... det er jo det rene ¤/(/¤#)(¤/)# verden ... hvor svært kan det være.

// ouT
Avatar billede janus_007 Nybegynder
13. maj 2008 - 01:36 #6
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å?
Avatar billede HenrikSjang Nybegynder
13. maj 2008 - 08:04 #7
Buzzzz skrev følgende: "at der skal være dette single column unique index."

Så en composite key kan desværre ikke bruges til fulltext search.
Avatar billede janus_007 Nybegynder
13. maj 2008 - 20:03 #8
Indlysende nu, tåget i nat *LOL*

- beklager!

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 :)
Avatar billede Syska Mester
13. maj 2008 - 21:34 #9
ServerID er til intern brug, det hele er på samme fysiske server ... og ja, det er en TinyInt allerede ...

Linked servers ... servere sat sammen i cluster af en art ?

Igen, hvad der så ikke er fortalt ... er at denne løsning ikke helt dur, da jeg skal kunne søge på dele af en string ... og ikke kun starten.

Dvs...
hvis man søger på "uper" skal den match "Superman" ... og det kan FTI ikke ...

LIKE '%uper%' kan ... men er darn langsom ... da den ikke kan bruge index, hvis man søger på en prefix ... men godt på en suffix.

Nogen der ved om MSSQL 2008 er værd at kigge på i den her sammenhæng ?

// ouT
Avatar billede janus_007 Nybegynder
14. maj 2008 - 22:29 #10
hej igen

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..."
Avatar billede Syska Mester
14. maj 2008 - 23:28 #11
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å ... :-)

// ouT
Avatar billede janus_007 Nybegynder
15. maj 2008 - 19:22 #12
Ja okay.. Det kan godt gå hen og blive svært.

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'

Bare en idé der fylder lidt hehe...
Avatar billede Syska Mester
16. maj 2008 - 13:40 #13
Ja, tror jeg bedre at jeg næsten kan leve med LIKE '%noget%' :-)

Men det er navne som nogen gange ikke giver mening ... online spil :-) og de kan være fra 1 til 20 tegn ... så det ville nok være lidt overkill ...

Et hjemmeside projekt, og bliver hentet via Ajax ... så de ca. 0.3 sek det kommer til at tage må jeg bare overleve ...

Ved du om der er kommet bedre muligheder i SQL 2008 ?

// ouT
Avatar billede janus_007 Nybegynder
16. maj 2008 - 16:02 #14
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.
Avatar billede Syska Mester
16. maj 2008 - 16:56 #15
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 :-)
Avatar billede HenrikSjang Nybegynder
16. maj 2008 - 17:59 #16
jamen så siger jeg da tak :)
Avatar billede janus_007 Nybegynder
16. maj 2008 - 20:29 #17
Tiptop dynomalygte :)
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