Page 1 of 2 1 2 LastLast
Results 1 to 15 of 30

Thread: Inladen grote datasets

  1. #1

    Inladen grote datasets

    Hallo iedereen,

    Ik zit met een probleem waarvan ik niet zeker weet of er wel een oplossing voor is :-)

    Het zit zo, we hebben enkele klanten met grote product catalogussen. 500.000 producten, 700.000 producten zijn geen uitzonderingen. Gegevens zijn opgeslagen in een Firebird database. Probleem is dat ze die gegevens willen beschikbaar hebben op de cliënt en de mogelijkheid willen om er vlot in te zoeken. Eerste probleem dat zich stelt is, hoe krijg ik die gegevens zo snel mogelijk op de cliënt pc... Uiteraard enige mogelijkheid is een query. (Is een nogal grote query met wat joins in en een groot aantal velden worden gefetcht). Je zou kunnen zeggen van : stel een basisfilter in alvorens de gegevens op te halen, maar dat gaat natuurlijk ook niet, want de klant wil de mogelijkheid om op alle velden te kunnen zoeken. Soms op artikelnummer, dan op omschrijving, kan ook op referentie leverancier zijn of op de naam van de leverancier, en ga zo maar door. Ik kan dus geen subset van de data opvragen, alles moet beschikbaar zijn. Zijn er mensen hier die al met 'big data' gewerkt hebben in zo een situaties?

    Dank bij voorbaat!!

  2. #2
    Ik zou als het even kan niet 500K aan producten ophalen. Bij dit soort aantallen ontkom je er bijna niet aan om dit in SQL te regelen. Op één of andere manier moet je het voor elkaar zien te krijgen om het filter van de eindgebruiker dus te vertalen naar SQL.

  3. #3
    Wat bedoel je met "op de cliënt pc"?
    Moet het daar offline beschikbaar zijn?
    Anders doe je het inderdaad met een server/client app die op het gewenste moment de juiste SQL uitvoert.

  4. #4
    Dat idee om alles te fetchen zal inderdaad niet het meest briljante zijn. Ik denk dat er niet aan te ontkomen valt dat zoveel records ophalen gewoon tijd neemt, vooral als je dan nog een grid koppelt. Als ik alles fetch met een gekopelde grid, dan duurt het 2 minuten en zie ik een geheurengebruik van 1,3 GB en dit voor aan standalone toepassing met 1 form en 1 query (heb een apart projectje aangemaakt om dit even te testen, de eigenlijke toepassing is natuurlijk een stuk groter). Lijkt me geen gezonde situatie. Zou ik het zo doen: Query openen, fetchall = false, grid koppelen die alleen vb de eerste 50 rijen visualiseert en dan filtering via query, zonder ooit alles te fetchen?

  5. #5
    Nee hoeft niet offline beschikbaar te zijn. Bedoel maar, het overbrengen van zoveel data naar een client pc duurt gewoon zo lang. Mensen begrijpen dat niet, die denken dat 500.000 records binnen de 2 seconden op hun scherm kunnen staan.

  6. #6
    Quote Originally Posted by stevedeclerck View Post
    Query openen, fetchall = false, grid koppelen die alleen vb de eerste 50 rijen visualiseert en dan filtering via query, zonder ooit alles te fetchen?
    Inderdaad. En op zich gaat dat al redelijk automatisch. Ik heb bijvoorbeeld een zoekscherm over een prijscourant.

    Click image for larger version. 

Name:	2020-05-20 10_23_38-Prijscourant.png 
Views:	178 
Size:	52.1 KB 
ID:	8091

    Bij de "Open" worden alleen de benodigde records opgehaald (Recordcount is dan b.v. 101). Pas als je gaat scrollen worden er door de TSQLQuery steeds meer records binnen getrokken.

    De SQL bouw ik dynamisch op, op het moment dat de gebruiker gegevens ingeeft.

  7. #7
    Rik, mooi scherm hoor! Het is inderdaad zoiets, met filtering op groepen, subgroepen, komt bijna precies overeen. Ok ik zal het inderdaad zo doen, zonder gekke dingen, bedankt !!

  8. #8
    Probleem is dat ze die gegevens willen beschikbaar hebben op de cliënt en de mogelijkheid willen om er vlot in te zoeken.
    Met de juiste queries kan je doorgaans ook snel zoeken, zónder alles eerst op de client te zetten.

    Het hangt er natuurlijk vanaf hoe je zoekt. Als je een zoekstring neemt, en een query opbouwt zoals die hieronder, dan weet je zeker dat het traag is. Je kan dan nooit gebruik maken van indexen, en je zal altijd je hele hoofdtabel (en waarschijnlijk de hele gejoinde tabellen) doorlopen.

    Code:
    where
      Naam like '%piet'%' or
      Straat like '%piet'%' or
      Bedrijfsnaam like '%piet'%' or
      ..
    Maar door de SQL samen te stellen op basis waarvan je wilt zoeken, en beperkingen te stellen aan _hoe_ je zoekt, kan je het een stuk efficienter maken. Als je bijvoorbeeld alleen wilt zoeken naar mensen die beginnen met 'piet', dan ziet je where clause er zo uit, en nu heeft je query ineens het voordeel van een index op de naam-kolom, en is ie misschien wel 100 keer sneller.

    Dat lijkt me ook het principe waar Rik's filters op gebaseerd zijn.
    Code:
    where
      Naam like 'piet'%'
    We gebruiken zelf zoek-schermpjes die er zo uitzien. Je kan dan als gebruiker opgeven waarin je zoekt. Gebruikers leren dan ook vanzelf dat zoeken op volledige naam (een samengesteld, ongeindexeerd veld), veel trager is dan op ordernummer of postcode. Dat gebruik je dus alleen bij uitzondering. En als het vaak voorkomt dat je wel op volledige naam moet zoeken, dan kunnen we zorgen dat dat beter geindexeerd is. Je kan er dan zelfs voor kiezen om indexen te maken op de wel of niet hoofdlettergevoelige variant, of een variant ontdaan van diacrieten, of (zoals bij telefoonnummers) ontdaan van spaties en leestekens.

    Je had het over big data, maar big data staat doorgaans ook niet op je client, en maakt gebruik van slimme indexeringen en slimme aggregaties/projecties waar je dan weer op doorqueriet. Een query op de ruwe data achter een big query systeem zal ook niet snel zijn. De truc is om zelden of nooit met de ruwe data te werken.
    Click image for larger version. 

Name:	order-zoeken.png 
Views:	162 
Size:	9.0 KB 
ID:	8092

    Onze zoekschermpjes zijn overigens aangepaste versies van de EST Search Dialogs.
    Last edited by GolezTrol; 20-May-20 at 13:11.
    1+1=b

  9. #9
    Ja inderdaad, zoekkolommen zouden moeten logisch zijn. In onze toepassing kan de klant instellen op welke kolommen er moet gezocht worden. Dat zou op zich moeten zo beperkt mogelijk blijven tot wat echt nodig is. Wat bedoel je om "niet met ruwe data te werken" ?
    Soms vraag ik me af hoe bedrijven zoals bvb Amazon dat doen, met miljoenen producten. Zoeken op hun site werkt eigenlijk behoorlijk snel.
    Wat ik me nog bijkomstig afvraag is of systemen zoals MySQL of MariaDB een verschil zouden maken in zo een uitgebreide zoekacties? Die beweren supersnel te zijn, maar kan ook marketing zijn natuurlijk...

    Bedankt voor de reactie...

  10. #10
    Die hebben specifieke indexeringen. Een simpele, maar vrij doeltreffende manier is de FULLTEXT index van MySQL. Die knipt een tekst op in woorden, en indexeert elk woord met een link naar de teksten in voorkomt, met een aantal metrics, bijvoorbeeld hoe vaak het voorkomt, hoeveel procent van de tekst uit dat woord bestaat, etc, om te bepalen hoe belangrijk dat woord is binnen de totale tekst. Als je dan zoekt op dat woord, dan kan die index snel vinden welke rijen relevant zijn voor dat woord, en hoe relevant dan wel.

    En dat bedoel ik met ruwe data. Een tabelletje waar je van begin tot eind door moet lopen is ruwe data die inefficient is om te lezen. Zodra je zelfs al een index toevoegt, maar je eigenlijk extra meta-data aan, voorwerwerkte varianten op je data, die je helpen met het zoeken in je data. Het bijwerken van die meta-data kost tijd, en het invoegen van een rij is trager als er een index op die tabel ligt, dan wanneer dat niet zo is. Het is dus altijd een afweging hoe veel van dat soort metadata je nodig hebt, en hoe die gestructureerd moet zijn om efficient te kunnen zoeken.

    En dan kom je weer bij aanvullende vraagstukken, zoals, hoe belangrijk is het dat die meta-data direct up to date is? Een index wordt doorgaans direct bijgewerkt, maar stel nou dat je een heel complex soort index hebt, zou het dan erg zijn als het eventjes duurt voordat je een nieuw product kan vinden? Zou het erg zijn als je een tijdje lang een out irrelevant product nog kan vinden? Voor een webshop als Amazon is dat niet zo'n probleem. Die zoekfunctie moet snel zijn, niet perfect.

    Bedrijven als Amazon, en zeker ook Google, hebben die principes gigantisch uitgewerkt om supersnel te kunnen zoeken met een meer dan acceptabel resultaat.

    Je kan, bijvoorbeeld, een apart tabelletje maken met zoekbare velden.
    In een zwaar genormaliseerde database, heb je een product, dat valt misschien onder een product range, die heeft misschien een fabrikant. Om dan alle producten van ACME te vinden, heb je een zware query nodig met minstens twee joins. Als je ook op andere gegevens wilt kunnen joinen, heb je misschien wel tien of meer joins in je query. Dan kan het al snel traag worden, zelfs als je redelijke indexen hebt. Die indexen liggen namelijk op 1 tabel.

    Maar daar kan je ook omheen werken. Je kan in sommige databases Materialized views gebruiken. Dat is eigenlijjk het resultaat van een query/view, platgeslagen in een tabel, die semi-automatisch bijgewerkt wordt als de data in de brontabellen verandert. Een materialized view kan je weer indexeren, en zo kan je een index maken op een combinatie van kolommen uit verschillende tabellen, of uit waarden die je normaal gesproken niet kan indexeren, zoals review-score, verwachte verkoop voor volgende week, etc.

    Voor een productcatalogus kan je ook een apart zoektabelletje maken. Coolblue heeft/had zoiets. Een apart tabelletje met product properties vul je met allerlei meta-gegevens. Dan weet je per product dus bijvoorbeeld dat het merk ACME is, welk type, productlijn, lengte, gewicht, prijs, of er een aanbieding is, noem maar op. Je zoekt dan altijd in hetzelfde lijstje, en dat kan veel efficienter zijn. Als je zoekt op 10 criteria, dan wil je dus alleen de producten met 10 matches hebben, of éérst de producten met 10 matches, en dan nog de net iets minder relevante producten met 9 of 8 matches.

    Eventueel kan je dat zelfs opslaan in een aparte database die minder geschikt is voor data-opslag en meer voor zoeken, zoals bijvoorbeeld Elasticsearch. Die regelt dat indexeren dat weer voor je op een andere manier dan een normale relationele database dat doet.
    1+1=b

  11. #11
    Mooie, interessante uitleg, zo leer ik weer bij. Bedankt !

  12. #12
    Full Text Search (FTS) werkt zeker goed en snel(!), maar het is niet altijd de oplossing.
    Een nadeel van FTS is, zoals Golez aangaf, dat de index teksten opdeelt in woorden. En dan kun je enkel op het begin van die woorden zoeken. Beetje zoals het LIKE 'piet%' voorbeeld.

    Stel dat je een product in je assortiment hebt met de naam "Botervloot'. Dan zal de FTS index dit indexeren als een enkel woord "Botervloot". Maar wat nou als je klant wilt zoeken op "vloot". In de Nederlandse (en sommige anderen) taal zijn samenvoeging zeer gebruikelijk en FTS werkt dan niet altijd lekker en je klanten zullen klagen omdat de hit rate te laag is. Slimmer tokenizen is aan te bevelen.

  13. #13
    Jup, dat kan je doen door te tokenizen, (dus 'botervloot' ook indexeren als 'boter' en 'vloot'). Je kan het ook oplossen met synonymenlijsten, dus 'vloot' vertalen naar 'botervloot' voordat je gaat zoeken. Nog een stapje verder is fuzzy matching, want wat als iemand 'bottervloot' tikt? Er zijn ook algoritmes om die weer te herleiden, en als er geen of weinig resultaten zijn, een andere zoekopdracht te gebruiken (of voor te stellen).

    Google doet dit ook met de 'bedoelde u soms "botervloot"?) Afhankelijk van of 'bottervloot' alleen relatief minder, of ook in absolute zin bijna niet voorkomt, zullen de zoekresultaten die van 'botervloot' of 'bottervloot' worden. Maar dat zijn dingen waar de meeste bedrijfsapplicaties nooit bij in de buurt komen, en zelfs de ingebouwde zoekmachines van grote websites (bijvoorbeeld die van NLDelphi of StackOverflow), komen niet in de buurt van wat Google op diezelfde site kan vinden.
    1+1=b

  14. #14
    Mooie aanvulling.
    Voor dergelijke zoek optimalisaties kun je de BK-Tree technologie gebruiken. Daarmee kan een tekst razendsnel in woorden opgesplitst worden, eventuele nabije (bottervloot) suggesties meenemen, en die tegen een woordenboek houden. Zo krijg je in een flits alle "relevante" zoek woorden uit een lap tekst terug. Die kun je dan weer indexeren in een FTS

    https://nullwords.wordpress.com/2013...pell-checking/
    Last edited by havezet; 21-May-20 at 20:54.

  15. #15
    met als extra opmerking dat soms de index daar behoorlijk groot van kan worden en daarmee mutaties op de database kan vertragen.

    Het afstappen van een fat client model en overstappen naar een thin client model maakt het werken met databases van deze omvang behoorlijk sneller. De gebruiker gaat dan niet meer merken dat er enorme hoeveelheden records in de database zitten.

    Enige pijnpunt kan nog worden als de records (ook al haal je er minder op) elk redelijk groot kunnen zijn ( bijv.vanwege plaatjes etc in de records) dat het netwerk alsnog van invloed kan zijn als dat netwerk al redelijk aan zijn max zit.

    PS vergeet niet je query plan te checken voor mogelijk problemen! fantastische tool om met grote databases je problemen te vinden.
    Last edited by Miep; 22-May-20 at 15:03.

Page 1 of 2 1 2 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •