[SQL] snel zoeken met 2 wildcards

Pagina: 1
Acties:
  • 446 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

  • zneek
  • Registratie: Augustus 2001
  • Laatst online: 08-02 14:52
Ik heb een SQL Server 2000 database met een tabel met >1.000.000 records. Deze tabel heeft een kolom "naam varchar(100)". Ik wil in deze kolom zoeken met 2 wildcards, en wel als volgt "%zoekterm%".

Nu heeft dat een vrij lang lopende query tot gevolg, +/- 8 seconden. Draai ik de query 3 keer achter elkaar dan lopen de tijden terug van 8 naar 4 naar 1 (allemaal +/-). Wacht ik na de derde keer 30 seconden en voer ik de query nog eens uit dan duurt het weer vrolijk 8 seconden.

Een index aanmaken op de kolom heeft alleen zin als je zoekt zonder start %, dus die oplossing valt af.

Een Full-Text index valt ook af, want ik wil op delen van woorden kunnen zoeken. Met Full-text kun je zoeken op "woord*" en dan "woordenboek" vinden, maar niet zoeken op "*boek" en dan "woordenboek" vinden. Wel vind je dan "ik heb een boek", omdat boek dan een los woord is in die zin.

Deze 2 standaard oplossingen, die ik al in meerdere topics hier op GoT terug gevonden heb kan ik dus niet inzetten. Nu vraag ik me af of er uberhaupt een manier is om zoekopdracht met dubbele wildcards snel uit te voeren?

Ik vermoed dat dit wel wil, maar dan met een gigantische dubbele administratie, waarin woorddelen oid opgeslagen worden, of per voorkomende letter in welke records deze allemaal voorkomt. Beide manieren om via een zooi metagegevens sneller het aantal records te beperken. Met meer dan 1.000.000 records kan dat wel eens een gigantische hoeveelheid extra MB's aan data opleveren.

Wat ik me daarnaast afvraag is waarom de query tijden van queries die vlak achter elkaar uitgevoerd worden zo laag liggen? Is dat een soort van tijdelijke cache oid? En is die cache in te stellen zodat die zoekresultaten langer beschikbaar blijven? Of vreet dat het interne geheugen van de server helemaal leeg? (SQL Server is al zo'n geheugen verslinder)

Ik ben zelf ook nog op zoek naar/aan het nadenken over alternatieve manieren van zoeken, maar tips zijn van harte welkom. Of is zoeken op een deel van een woord onmogelijk snel te doen?

[ Voor 3% gewijzigd door zneek op 25-05-2004 17:39 ]


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Bij mijn weten zit je met dit soort problemen altijd tegen ruimte-tijd oplossingen aan te hikken: Of het neemt meer ruimte in, maar is doorgaans sneller te doorzoeken. Of je doet een poging het efficient op te slaan (geen redundantie enzo) en het neemt daardoor meer tijd in.
Over het algmeen is ruimte goedkoper of makkelijker uit te breiden/alloceren en wordt er dus gekozen om wat meer ruimte in te laten nemen.

Als je vaak dezelfde queries hebt, dan zou je kunnen kijken naar het cachen van de zoekresultaten in een aparte tabel oid, dan duurt de eerste keer nog steeds vrij lang, maar daarna gaat het een stuk vlotter.
Anders ben je waarschijnlijk inderdaad aangewezen op een keur aan andere oplossingen die vooral neerkomen op het opsplitsen van je termen in losse delen (van bijv ieder 3 karakters). Er is wel wat lectuur over het snel doorworstelen van grote lijsten van termen met begin-wildcards, maar zelf heb ik me er nooit echt mee bezig gehouden.

Acties:
  • 0 Henk 'm!

  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

Lichtgewicht is sneller...
Heb je nog meer velden in die tabel staan? Een manier om de snelheid te verhogen is hem te versimpelen c.q. kleiner te maken. Hierdoor is de kans dat de gehele tabel ingeladen word een stuk groter.

Voor de beeldvorming: als je 1.000.000+ records inlaad in het ram geheugen (bijvoorbeeld in een c applicatie) dan kun je op de door jou gewenste manier in miliseconden het gewenste resultaat vinden.

Daarnaast zal om dezelfde reden een wat simpelere database als mysql ook sneller zijn.

seweso's blog


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

Wat betreft de searches zelf heb je het meeste al gezegd: LIKE-queries zijn langzaam, full-text kan niet op woorddelen zoeken. Tja :) Alternatieve oplossingen zul je zelf moeten implementeren, en dan ga je idd per lettergreep werken of iets vergelijkbaars zoals ACM aangeeft.

SQL Server is geen geheugenverslinder wat je zegt, allesbehalve zelfs! Als jij instelt dat ie maar 4Mb geheugen mag gebruiken doet hij dat netjes. Dat je queries vervolgens traag als dikke stront door een trechter lopen is een 2e :+ Default instelling is dat ie dynamisch geheugen trekt tussen de 0Mb en je hele fysieke RAM (!!!). Dit wordt inderdaad gebruikt om execution plans, indexes en (intermediate) results te cachen, vandaar dat subsequent identieke (of vergelijkbare) queries veel sneller zijn. Dit kun je overigens in Enterprise Manager of Computer Management bij de SQL Server Properties wijzigen (tabje 'Memory').

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

seweso schreef op 25 mei 2004 @ 23:57:
Voor de beeldvorming: als je 1.000.000+ records inlaad in het ram geheugen (bijvoorbeeld in een c applicatie) dan kun je op de door jou gewenste manier in miliseconden het gewenste resultaat vinden.
We hebben het wel over getallen in de orde van grootte van 100MB he... Daar (wildcard-)searches in doen zal ook in C niet altijd in milliseconden te doen zijn...
Daarnaast zal om dezelfde reden een wat simpelere database als mysql ook sneller zijn.
Ook in MySQL blijft dit werk dat in orden van groottes in seconden uitgedrukt zal worden. Om het echt efficient te doen zal er een handigere opslag gebruikt moeten worden, gok ik :)

Acties:
  • 0 Henk 'm!

  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

Kun je character 100 niet wat kleiner maken?

Misschien is wat achtergrond informatie ook leuk/handig :)

seweso's blog


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:04
seweso schreef op 26 mei 2004 @ 11:50:
Kun je character 100 niet wat kleiner maken?
En wat zou dat uithalen mbt performance winst denk je? Helemaal niks.

Wat je wel kan doen, is kijken of je je query nog wat meer kunt verfijnen. Zijn er nog bepaalde velden waarop gefiltert moet worden, etc....

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

whoami schreef op 26 mei 2004 @ 11:51:
[...]

En wat zou dat uithalen mbt performance winst denk je? Helemaal niks.

Wat je wel kan doen, is kijken of je je query nog wat meer kunt verfijnen. Zijn er nog bepaalde velden waarop gefiltert moet worden, etc....
Volgens mij zal het doorlopen van 10mb in plaats van 100mb zeker een stuk sneller gaan.

seweso's blog


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:04
Zijn velden zijn varchar, wat dus wil zeggen dat de 'niet gebruikte char's' niet gepadded worden.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

whoami schreef op 26 mei 2004 @ 11:59:
Zijn velden zijn varchar, wat dus wil zeggen dat de 'niet gebruikte char's' niet gepadded worden.
Ik ben geen expert op het gebied van MS-SQL server, maar varchar(100) betekent dat als je de data opvraagt er geen extra spaties in gezet worden, maar de ruimte is nog steeds gereserveerd. Daarom is 1.000.000 records x 100 karakters = 100mb. Bij een flexibele veldlengte zal de grote van de database bepaald worden door de manier waarop de database word gevuld. Stel dat het veld gemiddeld met 10 karakters word gevuld krijg je maar een database van 10mb. En daar fiets je zo doorheen. Maar ik moet toegeven dat dat niet de meest elegante oplossing is. Nu heb je O = n en je wil O = n0.x (O = zoektijd, n = aantal records).

Spellings-controle-programma's hebben trouwens ook met dit probleem te maken, misschien dat de TS naar pspell kan kijken.

seweso's blog


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:04
Het probleem is dat er een table scan gebeurd, en dat er geen indexen kunnen gebruikt worden. Dat is de vertragende factor. Alle rows moeten dus 1 voor 1 bekeken worden.
Het vergelijken v/d inhoud opzich zal wel niet zo significant zijn mbt de performance in dit geval

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

seweso schreef op 26 mei 2004 @ 12:16:
[...]
Ik ben geen expert op het gebied van MS-SQL server, maar varchar(100) betekent dat als je de data opvraagt er geen extra spaties in gezet worden, maar de ruimte is nog steeds gereserveerd. Daarom is 1.000.000 records x 100 karakters = 100mb.
Helaasch, SQL Server Books Online zegt:
varchar

Variable-length non-Unicode character data with length of n bytes. n must be a value from 1 through 8,000. Storage size is the actual length in bytes of the data entered, not n bytes. The data entered can be 0 characters in length. The SQL-92 synonyms for varchar are char varying or character varying.

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Overigens is het aan de implemenatie om te bepalen hoeveel bytes aan ruimte er wordt gealloceerd. Soms zal er inderdaad de volle varchar voor genomen worden, soms dus het aantal "bezette" bytes (plus wat overhead). Daar zegt de SQL Specificatie (uiteraard) niets over en zal je per server uit moeten vogelen.

Acties:
  • 0 Henk 'm!

  • The Eagle
  • Registratie: Januari 2002
  • Laatst online: 23:39

The Eagle

I wear my sunglasses at night

Zoals je zelf al aangeeft, lopen bij snel achter elkaar draaien je snelheden op, en dalen dus je tijden. Nou ken ik SQL-server niet (werk zelf met Oracle), maar als ik je zo hoor duidt er alles op dat er binnen 30 seconden na de query, je cache buffer wordt geleegd. Geen idee of dat in MSSQL is in te stellen, maar je zou eens kunnen kijken of je je cache-flush tijd wat groter zou kunnen maken. Zeker als deze query vaak gedraaid wordt, zal dat een stuk schelen gok ik zo - de data blijft dan nl veel langer in het snellere geheugen staan. 100 MB naar RAM schrijven duurt ook even he ;)

Al is het nieuws nog zo slecht, het wordt leuker als je het op zijn Brabants zegt :)


Acties:
  • 0 Henk 'm!

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
Even een gek idee spuien ;) :
Als je alleen op het begin of het eind van een woord wilt zoeken, zou je ook de naam normaal en in omgekeerde volgorde kunnen opslaan.
Het kost wel twee keer zoveel ruimte en er moet ook steeds twee keer zoveel bijgewerkt worden, maar het zoeken met de full-text search is dan wel mogelijk.

Never underestimate the power of


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

The_Eagle schreef op 26 mei 2004 @ 13:20:
Zoals je zelf al aangeeft, lopen bij snel achter elkaar draaien je snelheden op, en dalen dus je tijden. Nou ken ik SQL-server niet (werk zelf met Oracle), maar als ik je zo hoor duidt er alles op dat er binnen 30 seconden na de query, je cache buffer wordt geleegd. Geen idee of dat in MSSQL is in te stellen, maar je zou eens kunnen kijken of je je cache-flush tijd wat groter zou kunnen maken. Zeker als deze query vaak gedraaid wordt, zal dat een stuk schelen gok ik zo - de data blijft dan nl veel langer in het snellere geheugen staan. 100 MB naar RAM schrijven duurt ook even he ;)
Er is geen vaste flushtijd, die kun je enkel prolongeren door meer RAM te alloceren oftewel bij te kopen. Rule #1: een DB-server heeft nooit genoeg RAM :)

Daarnaast hebben tabellen met 1 miljoen records de neiging vaak geupdate te worden, waardoor cached results invalidated worden. Daar doe je niets aan vanzelfsprekend...

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • zneek
  • Registratie: Augustus 2001
  • Laatst online: 08-02 14:52
Op verzoek een beetje achtergrond info.

Het betreft een SQL Server database met bedrijfsgegevens, de kolom waarin gezocht wordt is bedrijfsnaam. De zoekopdracht wordt vanuit een .asp pagina gedaan.

Wat curry684 zegt is waar. Het is niet te bepalen welke records precies geupdate worden, en wanneer. Feit is dat ze ge-update worden (geen honderden per dag, maar toch). Daarom zal een oplossing die meer dataopslag gebruikt ook nog erg dynamisch moeten zijn om update/inserts op de tabel ook te kunnen doorzoeken.

Ik twijfel nu tussen 2 opties:

1. Niets wijzigen in de database, maar wel in het zoekformulier. Daarin aangeven dat er gezocht kan worden op "hele woorden" met een korte uitleg erbij wat dit precies in houdt, OF dat er gezocht kan worden op delen van woorden, met de waarschuwing er bij dat dit traag kan zijn.

2. Wel iets wijzigen in de database, en wel als volgt. Ik maak per cluster van records (zeg 10.000) een concatenatie veld aan. In dit veld plak ik alle bedrijfsnamen van de 10.000 bijbehorende bedrijven, en sla op welke range van bedrijfsids er bij hoort. Zo kan ik eerst een zoekopdracht op de cluster tabel loslaten die me als antwoord ranges van 10.000 records terug geeft waar het gezochte woord in gevonden kan worden. Aan de hand van die ranges ga ik vervolgens de betreffende records weer met 2 wildcards doorzoeken.

De eerste methode werkt het simpelst, de aanpassing ligt namelijk bij de gebruiker :)

De tweede weet ik niet of dat gaat werken. Als ik vanmiddag nog tijd over heb ga ik dat eens proberen. Ik post de resultaten nog wel even als ik er aan toe ben gekomen.

Acties:
  • 0 Henk 'm!

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
zneek schreef op 26 mei 2004 @ 14:14:
Ik twijfel nu tussen 2 opties:

1. Niets wijzigen in de database, maar wel in het zoekformulier. Daarin aangeven dat er gezocht kan worden op "hele woorden" met een korte uitleg erbij wat dit precies in houdt, OF dat er gezocht kan worden op delen van woorden, met de waarschuwing er bij dat dit traag kan zijn.

2. Wel iets wijzigen in de database, en wel als volgt. Ik maak per cluster van records (zeg 10.000) een concatenatie veld aan. In dit veld plak ik alle bedrijfsnamen van de 10.000 bijbehorende bedrijven, en sla op welke range van bedrijfsids er bij hoort. Zo kan ik eerst een zoekopdracht op de cluster tabel loslaten die me als antwoord ranges van 10.000 records terug geeft waar het gezochte woord in gevonden kan worden. Aan de hand van die ranges ga ik vervolgens de betreffende records weer met 2 wildcards doorzoeken.

De eerste methode werkt het simpelst, de aanpassing ligt namelijk bij de gebruiker :)

De tweede weet ik niet of dat gaat werken. Als ik vanmiddag nog tijd over heb ga ik dat eens proberen. Ik post de resultaten nog wel even als ik er aan toe ben gekomen.
Het voordeel van optie 2 zie ik eerlijk gezegd niet zo. Je gaat dan in 10.000 keer zo weinig records zoeken, maar je records zijn alleen ook 10.000 keer zo "groot" geworden :? Of begrijp ik het niet goed?

Never underestimate the power of


Acties:
  • 0 Henk 'm!

  • zneek
  • Registratie: Augustus 2001
  • Laatst online: 08-02 14:52
cameodski schreef op 26 mei 2004 @ 14:23:
[...]

Het voordeel van optie 2 zie ik eerlijk gezegd niet zo. Je gaat dan in 10.000 keer zo weinig records zoeken, maar je records zijn alleen ook 10.000 keer zo "groot" geworden :? Of begrijp ik het niet goed?
Ja, en dus wordt er 1 SQL iteratie uitgevoerd, en 1 zwaar string vergelijk statement ipv 10.000 SQL iteraties met 1 lichte string vergelijk.

Ik heb geen idee wat het effect is :) Maar het experiment is wel leuk.

Acties:
  • 0 Henk 'm!

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
zneek schreef op 26 mei 2004 @ 16:50:
[...]


Ja, en dus wordt er 1 SQL iteratie uitgevoerd, en 1 zwaar string vergelijk statement ipv 10.000 SQL iteraties met 1 lichte string vergelijk.

Ik heb geen idee wat het effect is :) Maar het experiment is wel leuk.
Ik betwijfel of het zoeken in 10.000 keer max. 100 karakters trager is dan het zoeken in 1 keer max. 1.000.000 karakters.
En daar komt nog bij dat je dergelijke lange teksten niet in een varchar veld kwijt kunt en zul je dus text velden moeten gaan gebruiken en die zijn aanzienlijk trager.
Vervolgens kun je je ook nog afvragen wat het kost om een dergelijke lange strings te onderhouden. Wat ga je bijvoorbeeld doen als er een record toegevoegd/gewijzigd/verwijderd wordt?

Never underestimate the power of


Acties:
  • 0 Henk 'm!

  • d00d
  • Registratie: September 2003
  • Laatst online: 16-09 13:23

d00d

geen matches

ik heb zelf even geen tabel met een miljoen varchar(100) records bij de hand, maar wat je zou kunnen proberen is het volgende.

Doe eerst een "where naam like 'boek%'" in een subquery, en doe vervolgens een "where naam like '%boek'" in de hoofdquery. Ik kan het zo uit mijn hoofd niet helemaal met zekerheid zeggen, maar volgens mij zal er dan geen table scan plaatsvinden.

niet vergeten eerst een index op naam te zetten voordat je dit test ;)

42.7 percent of all statistics are made up on the spot.


Acties:
  • 0 Henk 'm!

  • zneek
  • Registratie: Augustus 2001
  • Laatst online: 08-02 14:52
d00d schreef op 26 mei 2004 @ 17:17:
ik heb zelf even geen tabel met een miljoen varchar(100) records bij de hand, maar wat je zou kunnen proberen is het volgende.

Doe eerst een "where naam like 'boek%'" in een subquery, en doe vervolgens een "where naam like '%boek'" in de hoofdquery. Ik kan het zo uit mijn hoofd niet helemaal met zekerheid zeggen, maar volgens mij zal er dan geen table scan plaatsvinden.

niet vergeten eerst een index op naam te zetten voordat je dit test ;)
Dat gaat niet werken, aangezien de eerste "boekenplank" wel vindt, maar "woordenboek" niet. De tweede query voegt dan niets meer toe. Bovendien is zoeken op '%boek' ongeveer net zo traag als zoeken op '%boek%' geloof ik.

[edit] hoe bedoel je dat sub- en hoofdquery precies? Geef eens een voorbeeld

[ Voor 24% gewijzigd door zneek op 26-05-2004 17:31 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Middag , ik lees dit nu zo een beetje door en dacht ik ga eens iets heel doms roepen :+

Zelf had ik ook een bestand met enkele duizende entries.
Ook dit werdt heel erg traag met een *zoekstring* methode.

De oplossing die ik toen bedacht had, was het bestand op splitsen in alfabet vakken.

A-D / E-H / I-M ........

Een script keek vervolgens waar je op zoeken wilde, en selecteerde dat vak waar je woord in voor kwam.

Kortom een kleine bestandsvak om door te spitten , waardoor ik meer snelheid terug kreeg.

Is zo een dergelijke oplossing niets voor jouw ?

Acties:
  • 0 Henk 'm!

  • zneek
  • Registratie: Augustus 2001
  • Laatst online: 08-02 14:52
Verwijderd schreef op 27 mei 2004 @ 13:53:
Middag , ik lees dit nu zo een beetje door en dacht ik ga eens iets heel doms roepen :+

Zelf had ik ook een bestand met enkele duizende entries.
Ook dit werdt heel erg traag met een *zoekstring* methode.

De oplossing die ik toen bedacht had, was het bestand op splitsen in alfabet vakken.

A-D / E-H / I-M ........

Een script keek vervolgens waar je op zoeken wilde, en selecteerde dat vak waar je woord in voor kwam.

Kortom een kleine bestandsvak om door te spitten , waardoor ik meer snelheid terug kreeg.

Is zo een dergelijke oplossing niets voor jouw ?
Niet echt. Wat je voorstelt zorgt er misschien voor dat zoeken op 'woord%' sneller gaat, en doet hetzelfde als een index op de betreffende kolom. Zoeken op '%woord%' betekent dat je ook woorden wilt vinden waarvan je niet de startletter(s) weet.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur®

!litemod

Verwijderd schreef op 27 mei 2004 @ 13:53:
Middag , ik lees dit nu zo een beetje door en dacht ik ga eens iets heel doms roepen :+

Zelf had ik ook een bestand met enkele duizende entries.
Ook dit werdt heel erg traag met een *zoekstring* methode.

De oplossing die ik toen bedacht had, was het bestand op splitsen in alfabet vakken.

A-D / E-H / I-M ........

Een script keek vervolgens waar je op zoeken wilde, en selecteerde dat vak waar je woord in voor kwam.

Kortom een kleine bestandsvak om door te spitten , waardoor ik meer snelheid terug kreeg.

Is zo een dergelijke oplossing niets voor jouw ?
Voor het zoeken in bestanden werkt dit zeker erg goed, maar een database doet dit zelf al. Dit in een DB gebruiken werkt eerder vertragend.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Als ik moet raden wat het snelste is, dan zou ik zoiets bedenken:
Sla een woord als woordenboek op als:
woordenboek
ordenboek
denboek
nboek
oek
k

En als iemand dan zoekt op *boek*
Zoek dan op:
boek* OR oek*

Maar ruimte technisch is het natuurlijk niet zo'n mooie oplossing. Eventueel kan je er voor kiezen grotere stappen op te slaan en daardoor dus meer losse termen te genereren in je query. (met een stap van 3 letters moet je op boek*, oek* en ek* zoeken)
Achteraf moet je waarschijnlijk nog controleren of er ook daadwerkelijk *boek* instond, maar de ruwe voorselectie kan significant uitmaken in termen van performance.

[ Voor 15% gewijzigd door ACM op 27-05-2004 14:37 ]


Acties:
  • 0 Henk 'm!

Verwijderd

wss iets heel erg dom, maar toch:
is het niet mogelijk om de gegevens per lengte te sorteren:
bv. alle woorden van 2 letters -- alle woorden van 3 letters -- ... alle woorden van a letters

als iemand dan een dubbele query invult dan moet je pas beginnen te zoeken in de gevens die minstens 1 letter meer hebben dan de query

maar dit is mss al standaard geïmplementeerd in sql

Acties:
  • 0 Henk 'm!

  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

ACM schreef op 27 mei 2004 @ 14:36:
Als ik moet raden wat het snelste is, dan zou ik zoiets bedenken:
Sla een woord als woordenboek op als:
woordenboek
ordenboek
denboek
nboek
oek
k

En als iemand dan zoekt op *boek*
Zoek dan op:
boek* OR oek*

Maar ruimte technisch is het natuurlijk niet zo'n mooie oplossing. Eventueel kan je er voor kiezen grotere stappen op te slaan en daardoor dus meer losse termen te genereren in je query. (met een stap van 3 letters moet je op boek*, oek* en ek* zoeken)
Achteraf moet je waarschijnlijk nog controleren of er ook daadwerkelijk *boek* instond, maar de ruwe voorselectie kan significant uitmaken in termen van performance.
Ik heb even zoiets getest met 1.9 miljoen bedrijven, alleen niet met fysiek redundante informatie te genereren maar door slimme index expressies te gebruiken.

Ik heb de volgende 60 indexen gegenereerd
code:
1
2
3
4
INDEX ON SUBSTR(Handelsnaa + Handelsna2, 1) FOR !EMPTY(SUBSTR(Handelsnaa + Handelsna2, 1)) TAG NAAM1 
INDEX ON SUBSTR(Handelsnaa + Handelsna2, 2) FOR !EMPTY(SUBSTR(Handelsnaa + Handelsna2, 2)) TAG NAAM2
INDEX ON SUBSTR(Handelsnaa + Handelsna2, ..) FOR !EMPTY(SUBSTR(Handelsnaa + Handelsna2, ..)) TAG NAAM..
INDEX ON SUBSTR(Handelsnaa + Handelsna2, 60) FOR !EMPTY(SUBSTR(Handelsnaa + Handelsna2, 60)) TAG NAAM60

Mijn data bestand is dan 118 mb en de indexen zijn 776 mb.

Zoeken duurt dan 0.01 s (met een speciaal geschreven zoekfunctie). Als je ook zulke indexen kan aanmaken in je SQL server.. dan is dit dé oplossing. :7

seweso's blog


Acties:
  • 0 Henk 'm!

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
seweso schreef op 27 mei 2004 @ 16:37:
[...]
Ik heb even zoiets getest met 1.9 miljoen bedrijven, alleen niet met fysiek redundante informatie te genereren maar door slimme index expressies te gebruiken.

Ik heb de volgende 60 indexen gegenereerd
code:
1
2
3
4
INDEX ON SUBSTR(Handelsnaa + Handelsna2, 1) FOR !EMPTY(SUBSTR(Handelsnaa + Handelsna2, 1)) TAG NAAM1 
INDEX ON SUBSTR(Handelsnaa + Handelsna2, 2) FOR !EMPTY(SUBSTR(Handelsnaa + Handelsna2, 2)) TAG NAAM2
INDEX ON SUBSTR(Handelsnaa + Handelsna2, ..) FOR !EMPTY(SUBSTR(Handelsnaa + Handelsna2, ..)) TAG NAAM..
INDEX ON SUBSTR(Handelsnaa + Handelsna2, 60) FOR !EMPTY(SUBSTR(Handelsnaa + Handelsna2, 60)) TAG NAAM60

Mijn data bestand is dan 118 mb en de indexen zijn 776 mb.

Zoeken duurt dan 0.01 s (met een speciaal geschreven zoekfunctie). Als je ook zulke indexen kan aanmaken in je SQL server.. dan is dit dé oplossing. :7
En hoeveel tijd gaat het dan kosten als je een record wijzigt. Dan moeten er dus 100 indexen bijgewerkt worden.
Volgens mij is ook dit een surrogaat oplossing en zeker NIET "de oplossing".

P.S. Zoiets kan in SQL Server volgens mij door indexed views aan te maken. Computed columns gebruiken, kan denk ik ook wel.

Never underestimate the power of


Acties:
  • 0 Henk 'm!

  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

cameodski schreef op 27 mei 2004 @ 16:45:
[...]

En hoeveel tijd gaat het dan kosten als je een record wijzigt. Dan moeten er dus 100 indexen bijgewerkt worden.
Volgens mij is ook dit een surrogaat oplossing en zeker NIET "de oplossing".

P.S. Zoiets kan in SQL Server volgens mij door indexed views aan te maken. Computed columns gebruiken, kan denk ik ook wel.
Een update zit nu op 0.3 seconde, wat natuurlijk belachelijk veel is. Persoonlijk zou ik die tabel ook alleen maar gaan gebruiken voor het zoeken en updates in de originele tabel uitvoeren.

Indexed views klinkt trouwens ook wel cool.

seweso's blog


Acties:
  • 0 Henk 'm!

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
seweso schreef op 27 mei 2004 @ 16:57:
[...]
Een update zit nu op 0.3 seconde, wat natuurlijk belachelijk veel is. Persoonlijk zou ik die tabel ook alleen maar gaan gebruiken voor het zoeken en updates in de originele tabel uitvoeren.
En hoe wil je je updates dan in je zoektabel verwerken? Volgens mij ontkom je er echt niet aan dat er zeer trage updates ontstaan of je moet het 's nachts gaan bijwerken, maar dan wordt het een grote puinhoop.
Indexed views klinkt trouwens ook wel cool.
Gaat ook een tijdrovende klus worden, dus schiet je uiteindelijk ook weinig mee op.

@TS: Als er geen of heel weinig updates uitgevoerd worden en als er veelvuldig in op deze manier gezocht moet worden, zou je één of andere in dit topic genoemde, ranzige oplossing kunnen gebruiken. In alle andere gevallen, blijft er volgens mij weinig over dan de trage wildcard search.

Never underestimate the power of


Acties:
  • 0 Henk 'm!

  • zneek
  • Registratie: Augustus 2001
  • Laatst online: 08-02 14:52
status update:

geexperimenteerd met de door mij genoemde verzamelrecords. Door een beperking van SQL Server kon ik geen 10000 bedrijfsnamen in 1 kolom kwijt (max 8000 chars, text type kun je niet mee concatten) maar max 80.

De zoekresultaten die ik kreeg verwarden me een beetje. Ze waren wel sneller, maar normale zoekopdrachten zijn opeens ook een stuk sneller. Verder het enige wat ik gewijzigd heb is het datatype van de naam kolom, van nvarchar naar varchar. Ik vermoedde al dat daar ook iets mee was, maar waarom de queries nu in +/- 1 seconde klaar zijn snap ik nog niet helemaal.

Acties:
  • 0 Henk 'm!

Verwijderd

ahum .......
was dus echt een domme opmerking :+
Maar ook domme opmerkingen kunnen nog wel eens naar oplossingen leiden :)

Jammer genoeg heb ik dus deze keer niet kunnen helpen.
volgende keer beter ;)

[ Voor 22% gewijzigd door Verwijderd op 27-05-2004 17:27 ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
zneek schreef op 27 mei 2004 @ 17:18:Verder het enige wat ik gewijzigd heb is het datatype van de naam kolom, van nvarchar naar varchar. Ik vermoedde al dat daar ook iets mee was, maar waarom de queries nu in +/- 1 seconde klaar zijn snap ik nog niet helemaal.
De oorzaak kun je makkelijk in de help vinden:
char and varchar
Fixed-length (char) or variable-length (varchar) character data types.

char[(n)]

Fixed-length non-Unicode character data with length of n bytes. n must be a value from 1 through 8,000. Storage size is n bytes. The SQL-92 synonym for char is character.

varchar[(n)]

Variable-length non-Unicode character data with length of n bytes. n must be a value from 1 through 8,000. Storage size is the actual length in bytes of the data entered, not n bytes. The data entered can be 0 characters in length. The SQL-92 synonyms for varchar are char varying or character varying.

nchar and nvarchar
Character data types that are either fixed-length (nchar) or variable-length (nvarchar) Unicode data and use the UNICODE UCS-2 character set.

nchar(n)

Fixed-length Unicode character data of n characters. n must be a value from 1 through 4,000. Storage size is two times n bytes. The SQL-92 synonyms for nchar are national char and national character.

nvarchar(n)

Variable-length Unicode character data of n characters. n must be a value from 1 through 4,000. Storage size, in bytes, is two times the number of characters entered. The data entered can be 0 characters in length. The SQL-92 synonyms for nvarchar are national char varying and national character varying.
M.a.w: Je gebruikt nu geen Unicode velden meer... :+
Zolang je uhm... zeg maar even "normale", of "ouderwetse", ascii gebruikt is er niks aan de hand. Gebruik je unicode data, dan heb je nu een probleem.

[ Voor 9% gewijzigd door RobIII op 27-05-2004 17:35 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • d00d
  • Registratie: September 2003
  • Laatst online: 16-09 13:23

d00d

geen matches

Misschien kun je dit eens proberen:

aanmaken van een tabel met een computed column:
code:
1
2
3
4
5
6
CREATE TABLE [dbo].[WildCard] (
    [id] [int] IDENTITY (1, 1) NOT NULL ,
    [name] [varchar] (100) NULL ,
    [rev_name] AS (reverse([name])) 
) 
GO


indexen d'r op:
code:
1
2
3
4
CREATE  INDEX [IX_WildCard_1] ON [dbo].[WildCard]([rev_name])
GO
CREATE  INDEX [IX_WildCard_2] ON [dbo].[WildCard]([name], [rev_name])
GO


testdata d'r in:
code:
1
2
3
4
insert into WildCard([name]) values ('woordenboek')
go
insert into WildCard([name]) values ('boekenkast')
go


select statement uitvoeren:
code:
1
select * from WildCard where name like ('boek%') or rev_name like ('keob%')


Nu kan SQL Server gebruik maken van de indices, volgens mij.

42.7 percent of all statistics are made up on the spot.


Acties:
  • 0 Henk 'm!

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
zneek schreef op 27 mei 2004 @ 17:18:
geexperimenteerd met de door mij genoemde verzamelrecords. Door een beperking van SQL Server kon ik geen 10000 bedrijfsnamen in 1 kolom kwijt (max 8000 chars, text type kun je mee concatten) maar max 80.
Volgens mij had ik je al verteld, dat je dan text of ntext moest gaan gebruiken :?
d00d schreef op 27 mei 2004 @ 17:33:
Misschien kun je dit eens proberen:

aanmaken van een tabel met een computed column:
code:
1
2
3
4
5
6
CREATE TABLE [dbo].[WildCard] (
    [id] [int] IDENTITY (1, 1) NOT NULL ,
    [name] [varchar] (100) NULL ,
    [rev_name] AS (reverse([name])) 
) 
GO


indexen d'r op:
code:
1
2
3
4
CREATE  INDEX [IX_WildCard_1] ON [dbo].[WildCard]([rev_name])
GO
CREATE  INDEX [IX_WildCard_2] ON [dbo].[WildCard]([name], [rev_name])
GO


testdata d'r in:
code:
1
2
3
4
insert into WildCard([name]) values ('woordenboek')
go
insert into WildCard([name]) values ('boekenkast')
go


select statement uitvoeren:
code:
1
select * from WildCard where name like ('boek%') or rev_name like ('keob%')


Nu kan SQL Server gebruik maken van de indices, volgens mij.
Bedankt voor het uitwerken van mijn al eerder geposte tip ;)
Jammer alleen dat het niet werkt als je op bijvoorbeeld %en% wilt zoeken en "en" staat niet aan het begin en ook niet aan het eind.

[ Voor 3% gewijzigd door cameodski op 27-05-2004 17:39 ]

Never underestimate the power of


Acties:
  • 0 Henk 'm!

  • d00d
  • Registratie: September 2003
  • Laatst online: 16-09 13:23

d00d

geen matches

cameodski schreef op 27 mei 2004 @ 17:39:

Bedankt voor het uitwerken van mijn al eerder geposte tip ;)
Jammer alleen dat het niet werkt als je op bijvoorbeeld %en% wilt zoeken en "en" staat niet aan het begin en ook niet aan het eind.
Jammer genoeg heb je daar ontzettend gelijk in! Zou eigenlijk ook *te* mooi zijn als het zo eenvoudig op te lossen was. Dan kon ik mijn geld gaan verdienen als SQL Server query optimizer programmeur bij Microsoft.

42.7 percent of all statistics are made up on the spot.


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

cameodski schreef op 27 mei 2004 @ 16:45:
En hoeveel tijd gaat het dan kosten als je een record wijzigt. Dan moeten er dus 100 indexen bijgewerkt worden.
Volgens mij is ook dit een surrogaat oplossing en zeker NIET "de oplossing".
Er is geen "de oplossing".
Je moet of ruimte opofferen (en redundantie introduceren) om de gegevens alvast "voor te bereiden" of je moet al dat voorwerk per zoektocht opnieuw doen.

Uiteraard zijn er nog wat tussenoplossingen, waar je wat schuift met de hoeveelheid voorwerk.
Die indices bijwerken (of velden veranderen, etc) is allemaal een of andere vorm van voorwerk. Je kan kiezen om de boel met de helft van die indices (of een derde, etc) uit te voeren, hoewel ik denk dat je beter niet minder dan de helft kan nemen. Je kan er ook voor kiezen om de boel in losse lettergrepen op te splitsen, of op veel voorkomende woordgroepen te hashen, etc etc etc.

Maar het is allemaal ruimte-kostend voorwerk dat je helpt het echte zoekwerk te vereenvoudigen... Zelfs caching valt daar onder.

Overigens zou ik het, denk ik, wel met een losse (deel)termen-tabel oplossen en daar een gewone (prefix)indexed search op proberen (hoewel de oplossing met functionele indices natuurlijk ook wel aardig is) te doen en die tabel dmv triggers bijgewerkt houden.

Wat de beste oplossing is kan ik alleen niet zeggen, dat hangt van de functionele eisen aan het zoeken af en de problemen die het oplevert als er per term in de orde van 1/2(n-1) * (n-2) oid extra ruimte gebruikt wordt enzo :P

[ Voor 19% gewijzigd door ACM op 27-05-2004 18:21 ]


Acties:
  • 0 Henk 'm!

  • zneek
  • Registratie: Augustus 2001
  • Laatst online: 08-02 14:52
cameodski schreef op 27 mei 2004 @ 17:39:
[...]

Volgens mij had ik je al verteld, dat je dan text of ntext moest gaan gebruiken :?
Ik was ook van plan text te gebruiken, maar kreeg zo snel niet een query in elkaar gezet die een verzameling van 10000 bedrijfsnamen in die ene kolom neerzet. Daarvoor zul je namelijk een varchar of text variabele aan de doel text variabele moeten concatten. En dat kan dus niet... Daarom heb ik voor een varchar(8000) gekozen, minder namen in 1 kolom, maar wel te vullen via een 'simpele' INSERT/UPDATE query constructie

Acties:
  • 0 Henk 'm!

Verwijderd

Ik zie eigenlijk niet waarom een gebruiker op '%oekhandel%' wil zoeken? Is dit daadwerkelijk iets wat in de praktijk voorkomt of is het omdat je denkt dat dit wel handig is voor een gebruiker?

Ik weet niet hoe er precies met de data gewerkt wordt, maar als ik kijk naar de praktijksituaties die ik ken, dan wordt er niet op '%oekhandel%' gezocht maar gewoon naar 'boekhandel%' of als de gebruiker lui(\slim) is naar 'boekh%'.

Ik kan alleen praktijksituaties waar men dus als bovenstande zoekt of naar woorden ergens in de bedrijfsnaamz, zoals: 'Petit' als ik naar 'Restaurant Le Petit' zoek. Een FullText Index zou in mijn ogen genoeg moeten zijn.

Zelf laat ik altijd een mogelijkheid open voor gebruikers om toch op '%oekhandel%' te zoeken, maar dan weten ze dat het langer gaat duren voordat er resultaat is.

Het kan natuurlijk zijn dat jij een praktijksituatie hebt die dit echt vereist, dan kun je bovenstaande als niet gepost beschouwen ;).

-Rémy

Acties:
  • 0 Henk 'm!

  • RichTech
  • Registratie: September 2001
  • Laatst online: 09-07 21:39
Wellicht is er een oplossing door niet alle resultaten te willen tonen. Indien je een aantal resultaten gevonden hebt die op 1 pagina getoond kunnen worden, zeg 25 ofzo, dan kan het zoeken stoppen.

Heb je snel 25 hits, dan stopt het zoekproces en toon je de resultaten. Bij een volgende keer zoeken moet je uiteraard starten waar je gestopt bent.

Ik heb een dergelijke SQL als eens een keer op m'n werk voorbij zien komen, maar het exacte commando ken ik zo niet, wellicht iemand anders??

Acties:
  • 0 Henk 'm!

Verwijderd

en als je LOCATE gebruikt ipv LIKE... zou dat niet sneller gaan...
ik kan het helaas niet testen omdat ik ook niet echt zo'n grote db bij de hand heb hier..

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Verwijderd schreef op 27 mei 2004 @ 20:41:
Ik kan alleen praktijksituaties waar men dus als bovenstande zoekt of naar woorden ergens in de bedrijfsnaamz, zoals: 'Petit' als ik naar 'Restaurant Le Petit' zoek. Een FullText Index zou in mijn ogen genoeg moeten zijn.
"Visrestaurant de Haring" (kweenie of die bestaat) en iemand wil zoeken naar alle bedrijven met 'restaurant' in de naam, full text index zal deze niet vinden.

Ik ben het met je eens dat iemand niet naar 'khandel' zal zoeken, eerder naar 'boekh', maar aangezien het vrij lastig is alle te zoeken deelwoorden te voorspellen, kan je wellicht beter alle mogelijke deelwoorden meenemen.

Acties:
  • 0 Henk 'm!

Verwijderd

ACM schreef op 27 mei 2004 @ 21:41:
[...]

"Visrestaurant de Haring" (kweenie of die bestaat) en iemand wil zoeken naar alle bedrijven met 'restaurant' in de naam, full text index zal deze niet vinden.

Ik ben het met je eens dat iemand niet naar 'khandel' zal zoeken, eerder naar 'boekh', maar aangezien het vrij lastig is alle te zoeken deelwoorden te voorspellen, kan je wellicht beter alle mogelijke deelwoorden meenemen.
Oké, "Visrestaurant de Haring" zal niet gevonden worden, maar is er een praktijksituatie die hier om vraagt? Dat wil ik duidelijk maken! Aangezien zoeken op restaurant in de bedrijfsnaam niet betekend dat je alle restaurants hebt (waarom zou dit in de bedrijfsnaam staan...)

Wanneer wil je zeer snel zoeken op bedrijfsnaam? Meestal kom je dan uit bij een telefonische onderhoud tussen een klant(een bedrijf) en een werknemer. De klant stelt zich hierbij voor ("Goedemiddag, ik ben Pietje Puk van restaurant de Haring"). De werknemer wil zo snel mogelijk de klantgegevens erbij hebben en zal dan niet op restaurant gaan zoeken maar op 'Haring'. En als Haring geen zoekresultaat oplevert dan zou een werknemer misschien 'restaurant' proberen. Als dit ook geen resultaat oplevert (of teveel), dan zal een werknemer op een andere manier gaan zoeken (en vragen gaan stellen aan de klant.), zoals postcode, deb.nr, tel.nr etc.

Dus als er een goede reden is om %oekhandel% te zoeken in een bedrijfsnaam dan heb ik niets gezegd, maar ik wil alleen aangeven of %oekhandel% wil een echte praktijksituatie is (en ik betwijfel dat ;)).

-Rémy

Acties:
  • 0 Henk 'm!

  • zneek
  • Registratie: Augustus 2001
  • Laatst online: 08-02 14:52
Verwijderd schreef op 27 mei 2004 @ 22:42:
[...]
Oké, "Visrestaurant de Haring" zal niet gevonden worden, maar is er een praktijksituatie die hier om vraagt? Dat wil ik duidelijk maken! Aangezien zoeken op restaurant in de bedrijfsnaam niet betekend dat je alle restaurants hebt (waarom zou dit in de bedrijfsnaam staan...)

Wanneer wil je zeer snel zoeken op bedrijfsnaam? Meestal kom je dan uit bij een telefonische onderhoud tussen een klant(een bedrijf) en een werknemer. De klant stelt zich hierbij voor ("Goedemiddag, ik ben Pietje Puk van restaurant de Haring"). De werknemer wil zo snel mogelijk de klantgegevens erbij hebben en zal dan niet op restaurant gaan zoeken maar op 'Haring'. En als Haring geen zoekresultaat oplevert dan zou een werknemer misschien 'restaurant' proberen. Als dit ook geen resultaat oplevert (of teveel), dan zal een werknemer op een andere manier gaan zoeken (en vragen gaan stellen aan de klant.), zoals postcode, deb.nr, tel.nr etc.

Dus als er een goede reden is om %oekhandel% te zoeken in een bedrijfsnaam dan heb ik niets gezegd, maar ik wil alleen aangeven of %oekhandel% wil een echte praktijksituatie is (en ik betwijfel dat ;)).

-Rémy
Los van het feit of er op gezocht wordt (wat natuurlijk zou kunnen in het visrestaurant voorbeeld) zat deze functionaliteit in de applicatie toen deze opgeleverd werd. De klant heeft alleen later besloten de +/- 100.000 records uit te breiden naar +1.000.000. Vandaar dat dit probleem nu optreedt. Met 100.000 records was de zoekfunctie al niet bijster snel, maar nog wel acceptabel. Met 1.000.000 is de grens van acceptabel dus overschreden :)

Vandaag contact met de betreffende klant gezocht en het gaat de volgende oplossing worden: de gebruiker krijgt de mogelijkheid om bij het zoeken te kiezen of er op hele woorden (middels full-text) of op delen van woorden (middels een 'gewone' '%woord%' ) gezocht moet worden, met daarbij de melding dat op delen van woorden zoeken trager is.

Altijd een irritante tweestrijd, van klant-wensen en budget aan de ene kant, en de developer/programmeur aan de andere kant. Hoewel ik hier graag nog eens een dag of wat mee zou willen stoeien, is de klant niet bereid daar voor te betalen. En ik heb simpelweg niet genoeg vrije tijd om die hier aan te besteden.

Mocht iemand nog een leuke oplossing weten, ik heb een kopie van de db gemaakt waar ik in kan rotzooien wat ik wil :) Ik ga denk nog eens stoeien met die 60-voudige index zoals hierboven ergens beschreven.

Acties:
  • 0 Henk 'm!

  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

zneek schreef op 27 mei 2004 @ 23:42:
....Mocht iemand nog een leuke oplossing weten...
Mogelijke oplossingen zijn:
• Offline zoeken, als je op één of andere manier van te voren al weet wat er gezocht gaat worden kun je de resultaten alvast klaarzetten (bijvoorbeeld als je een vuil bestand moet matchen op je schonen 1.0000.000+ bestand)
• Getrapt zoeken a-la KaZaa, dus in eerste instantie grof en snel zoeken en als er vervolgens geen resultaat is kan de gebruiken ook een uitgebreide zoekactie starten.
• Zorgen dat alle namen in RAM geheugen komen te staan. Wellicht in C++ een active-x object maken die die doet en vervolgens deze vanuit ASP aanroepen (dat zal zeker een stuk sneller zijn, als tenminste niet voor elke connectie een object aanmaakt :P )
• Dieper ingaan op de reden waarom deze zoekfunctionaliteit nodig is en waarom er door zo'n groot bestand gezocht moet worden (grote kans dat iemand ergens kort door de bocht en lomp loopt na te denken).
• Contact met ons opnemen, aangezien wij expert zijn op het gebied van het zoeken en matchen van bedrijven (wij kunnen gemiddeld 95% van de meuk die mensen ons aanleveren matchen op alle bedrijven van Nederland).

seweso's blog


Acties:
  • 0 Henk 'm!

  • zneek
  • Registratie: Augustus 2001
  • Laatst online: 08-02 14:52
seweso schreef op 28 mei 2004 @ 01:05:
[...]
Mogelijke oplossingen zijn:
• Offline zoeken, als je op één of andere manier van te voren al weet wat er gezocht gaat worden kun je de resultaten alvast klaarzetten (bijvoorbeeld als je een vuil bestand moet matchen op je schonen 1.0000.000+ bestand)
Is niet te bepalen
• Getrapt zoeken a-la KaZaa, dus in eerste instantie grof en snel zoeken en als er vervolgens geen resultaat is kan de gebruiken ook een uitgebreide zoekactie starten.
Ik zie niet hoe? er wordt gezocht op '%woord%'. Eventueel met wat extra beperkende maatregelen (provincie, plaats). Dan presteert het zoeken prima, want die kriteria worden als eerst gebruikt, de text matching wordt dan over veel minder records gedaan. Ik zie niet hoe er een beperkend criterium op basis van alleen een '%woord%' zoekopdracht gedaan kan worden.
• Zorgen dat alle namen in RAM geheugen komen te staan. Wellicht in C++ een active-x object maken die die doet en vervolgens deze vanuit ASP aanroepen (dat zal zeker een stuk sneller zijn, als tenminste niet voor elke connectie een object aanmaakt :P )
Dat vind ik nog wel een idee om eens nader te onderzoeken. Maar met 1.000.000 x 100 chars wordt dan wel een behoorlijk geheugen vretend iets.
• Dieper ingaan op de reden waarom deze zoekfunctionaliteit nodig is en waarom er door zo'n groot bestand gezocht moet worden (grote kans dat iemand ergens kort door de bocht en lomp loopt na te denken).
Die uitleg staat er ergens in dit topic: de klant heeft er om gevraagd. Ik kan hem vertellen wat de nadelen van die keuze zijn, maar hij moet die keuze zelf maken.
• Contact met ons opnemen, aangezien wij expert zijn op het gebied van het zoeken en matchen van bedrijven (wij kunnen gemiddeld 95% van de meuk die mensen ons aanleveren matchen op alle bedrijven van Nederland).
Zal ik mijn klant direct maar helemaal naar jullie doorsturen :? ;) Zoals in mijn vorige post vermeld ben ik er uit hoe de oplossing voor de klant gaat worden. Verder ben ik geinteresseerd om te zien of er nog een leuke oplossing voor bedacht kan worden, puur voor 'future reference'.

[ Voor 4% gewijzigd door zneek op 28-05-2004 08:53 ]


Acties:
  • 0 Henk 'm!

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
seweso schreef op 28 mei 2004 @ 01:05:
[...]
Mogelijke oplossingen zijn:
• Offline zoeken, als je op één of andere manier van te voren al weet wat er gezocht gaat worden kun je de resultaten alvast klaarzetten (bijvoorbeeld als je een vuil bestand moet matchen op je schonen 1.0000.000+ bestand)
Bedoel je nu dat je denkt, dat je op je werkstationnetje sneller kunt zoeken dan dat een SQL Server beest dat kan? Kunnen jullie dan ook niet iets maken dat SQL Server vervangt :?
• Zorgen dat alle namen in RAM geheugen komen te staan. Wellicht in C++ een active-x object maken die die doet en vervolgens deze vanuit ASP aanroepen (dat zal zeker een stuk sneller zijn, als tenminste niet voor elke connectie een object aanmaakt :P )
Als er op de SQL Server genoeg geheugen is, zou het zomaar kunnen dat daar de namen ook al in het geheugen terecht komen. ;)
En de kans dat er in de SQL Server veel geheugen zit, is groter dan op het werkstation van alle gebruikers.
SQL Server gebruikt zijn geheugen natuurlijk voor nog meer dingen, maar dan nog is het beter om daar alles te laten gebeuren.

Never underestimate the power of


Acties:
  • 0 Henk 'm!

  • pistole
  • Registratie: Juli 2000
  • Laatst online: 19:48

pistole

Frutter

whoami schreef op 26 mei 2004 @ 12:26:
Het probleem is dat er een table scan gebeurd, en dat er geen indexen kunnen gebruikt worden. Dat is de vertragende factor. Alle rows moeten dus 1 voor 1 bekeken worden.
Het vergelijken v/d inhoud opzich zal wel niet zo significant zijn mbt de performance in dit geval
Deze opmerking is volgens mij onterecht.
Ik heb hier een vergelijkbare tabel (maar dan 100,000 records met o.a. een varchar(150)) waarop ik een like '%blaat%' loslaat, maar die gaat prima door mijn index.

Een like clause op dit veld is binnen een seconde klaar en gebruikt de index die ervoor bedoelt is.
Als je table scans krijgt (execution plan?) dan zit er sowieso iets niet goed, lijkt me.
zneek schreef op 25 mei 2004 @ 17:39:
Een index aanmaken op de kolom heeft alleen zin als je zoekt zonder start %, dus die oplossing valt af.
Hoezo?

[ Voor 13% gewijzigd door pistole op 28-05-2004 09:15 ]

Ik frut, dus ik epibreer


Acties:
  • 0 Henk 'm!

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
pistole schreef op 28 mei 2004 @ 09:14:
[...]

Deze opmerking is volgens mij onterecht.
Ik heb hier een vergelijkbare tabel (maar dan 100,000 records met o.a. een varchar(150)) waarop ik een like '%blaat%' loslaat, maar die gaat prima door mijn index.

Een like clause op dit veld is binnen een seconde klaar en gebruikt de index die ervoor bedoelt is.
Als je table scans krijgt (execution plan?) dan zit er sowieso iets niet goed, lijkt me.
Dat lijkt me heel, heel stug. Welke database gebruik je? Ik zou niet weten hoe hier een index gebruikt moet worden.

Oops! Google Chrome could not find www.rijks%20museum.nl


Acties:
  • 0 Henk 'm!

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
pistole schreef op 28 mei 2004 @ 09:14:
[...]

Deze opmerking is volgens mij onterecht.
Ik heb hier een vergelijkbare tabel (maar dan 100,000 records met o.a. een varchar(150)) waarop ik een like '%blaat%' loslaat, maar die gaat prima door mijn index.

Een like clause op dit veld is binnen een seconde klaar en gebruikt de index die ervoor bedoelt is.
Als je table scans krijgt (execution plan?) dan zit er sowieso iets niet goed, lijkt me.
Ik denk dat jij misschien dan geen table scan hebt, maar wel een index scan en dat kan ook zomaar heel traag zijn.
En een index scan is heel wat anders dan geindexeerd kunnen zoeken.
[...]

Hoezo?
Dat heeft te maken met de manier waarop tekst gesorteerd wordt.
Als er dus gezocht moet worden op 'woorden%' weet SQL Server dat hij ergens bij de "w" moet zoeken als er gezocht moeten worden op '%woorden%' kan het overal staan en zal er dus een table of index scan plaatsvinden.

[ Voor 7% gewijzigd door cameodski op 28-05-2004 09:21 ]

Never underestimate the power of


Acties:
  • 0 Henk 'm!

  • pistole
  • Registratie: Juli 2000
  • Laatst online: 19:48

pistole

Frutter

P_de_B schreef op 28 mei 2004 @ 09:16:
[...]
Dat lijkt me heel, heel stug. Welke database gebruik je? Ik zou niet weten hoe hier een index gebruikt moet worden.
Mjah, je hebt gelijk - ik zie dat de optimizer de PK_ index pakt. Oeps.
Overigens gewoon SQL2k, wel een goed geoutilleerde machine natuurlijk.
cameodski schreef op 28 mei 2004 @ 09:20:
[...]

Ik denk dat jij misschien dan geen table scan hebt, maar wel een index scan en dat kan ook zomaar heel traag zijn.
En een index scan is heel wat anders dan geindexeerd kunnen zoeken.

[...]

Dat heeft te maken met de manier waarop tekst gesorteerd wordt.
Als er dus gezocht moet worden op 'woorden%' weet SQL Server dat hij ergens bij de "w" moet zoeken als er gezocht moeten worden op '%woorden%' kan het overal staan en zal er dus een table of index scan plaatsvinden.
Is inderdaad een Index scan.
Wat betreft het niet kunnen zoeken op een %blaat... Goed point, zo had ik het niet bedacht.

[ Voor 61% gewijzigd door pistole op 28-05-2004 09:25 ]

Ik frut, dus ik epibreer


Acties:
  • 0 Henk 'm!

  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

cameodski schreef op 28 mei 2004 @ 08:59:
[...]

Bedoel je nu dat je denkt, dat je op je werkstationnetje sneller kunt zoeken dan dat een SQL Server beest dat kan? Kunnen jullie dan ook niet iets maken dat SQL Server vervangt :?

[...]

Als er op de SQL Server genoeg geheugen is, zou het zomaar kunnen dat daar de namen ook al in het geheugen terecht komen. ;)
En de kans dat er in de SQL Server veel geheugen zit, is groter dan op het werkstation van alle gebruikers.
SQL Server gebruikt zijn geheugen natuurlijk voor nog meer dingen, maar dan nog is het beter om daar alles te laten gebeuren.
Beide voorbeelden die jij aanhaalt zul je beiden aan de server-kant uitvoeren. Ik had het woord 'offline' verkeerd gekozen, maar bij deze oplossing is van toepassing als je bijvoorbeeld een groot bestand met bedrijven hebt die je wil zoeken in een hoofd-bestand. Daarbij kun je de computer eerst alle zoekresultaten klaarzetten zodat als je deze handmatig door gaat lopen je een goede match kan maken.

Bij die andere oplossing kan ik niet helemaal volgen waarom je denkt dat dat op de client uitgevoerd gaat worden. Verder denk ik dat 100mb aan data niet echt veel is om in RAM geheugen te laden...

seweso's blog


Acties:
  • 0 Henk 'm!

  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
seweso schreef op 28 mei 2004 @ 13:39:
[...]
Beide voorbeelden die jij aanhaalt zul je beiden aan de server-kant uitvoeren. Ik had het woord 'offline' verkeerd gekozen, maar bij deze oplossing is van toepassing als je bijvoorbeeld een groot bestand met bedrijven hebt die je wil zoeken in een hoofd-bestand. Daarbij kun je de computer eerst alle zoekresultaten klaarzetten zodat als je deze handmatig door gaat lopen je een goede match kan maken.
Kun je dat klaarzetten van zoekresultaten nog wat verder toelichten, want ik snap echt niet hoe je dat dacht te doen en waarom dat sneller zou zijn.
Bij die andere oplossing kan ik niet helemaal volgen waarom je denkt dat dat op de client uitgevoerd gaat worden. Verder denk ik dat 100mb aan data niet echt veel is om in RAM geheugen te laden...
Dat woordje offline is wat te lang blijven hangen, denk ik _/-\o_

Never underestimate the power of

Pagina: 1