11. června 2012


Jak na vyhledávání ve velkých e-shopech


Pokud zákazník hledá něco v e-shopu, asi to chce koupit.
Toto nutí autory e-shopů, tlakem ze strany majitelů, aby prohledali každou potenciální shodu mezi hledaným výrazem a výrobkem.
U velkých e-shopů je to problém. Dat k prohledávání je spousta a databázové servery jsou pomalé, obzvlášť pokud se prohledávají tabulky na výskyt části řetězce, nebo regulární výrazy.
Přitom si jenom málokdo uvědomí, že se jedná o násobení matic.

Jak z toho ven?

Zkratka první - nenásobte matice

Nabídněte výsledky z:
- kategorií
- názvů zboží
- popisů zboží
- recenzí na zboží
- ...
Třeba postupně, máme přece AJAX

Zkratka druhá - normalizujte

Každé slovo které napíšete uložíte do tabulky a přiřadíte mu index. V textu použijete místo slova index slova.
Pak stačí prohledat jednu obrovskou tabulku indexů.

Zkratka třetí - otočte směr

Vytvořte si tabulku vyhledávaných výrazů a odpovídajících dokumentů. Neosvobodí vás to od prohledávání celých tabulek pro nově hledané výrazy, ale poskytne to možnost nabídnout ty nejhledanější výrazy a odkazy na relevantní zboží. Dá se to propojit se SEO a celou obchodní logikou. Proč držet skladem zboží, které nikdo nehledá?

Zkratka čtvrtá - zrychlete server

Tohle řešení bývá nejčastější a nejrychlejší.
Špatné zadání, dodatečné úpravy, špatný odhad reálné návštěvnosti, ...  Skvělý model se zhroutil a je potřeba najít řešení. Tady je. Je relativně prosté.
Pokud máte na serveru hromadu zbytečné paměti, tak se dá použít.
Dejme tomu, že máte MySQL server a na něm tabulky o velikostech v řádu jednotek GB. Přečtení a prohledání takové tabulky, trvá cca stejně jako její prohledání příkazem grep. Musíte ji prostě celou přečíst z disku + nějaká režie navíc. Největší problém, ale není čtení. Největší problém je zápis. Jestliže použijete UNION, nebo JOIN, nebo WHERE tabluka1.id=tabulka2.id pak dochází k násobení matic a zpravidla i k ukládání takto vytvořených dočasných tabulek na disk.
Jak zrychlit disk? Např. použitím filesystému s vysokou propustností (dejme tomu získáme 30%).
Použitím SAS disků místo SATA, nebo třeba použitím SDD místo SAS. To je dobrá cesta. Použijeme SDD, XFS, zarovnáme partition table, upravíme některé parametry XFS, parametry mount, ...
No a co takhle úplně eliminovat zápisy na disk? Upravit velikosti cache a bufferů v MySQL, použít tpmfs na /tmp
Nebo to chcete úplně bezpečné? Tak použijte replikaci na server který používá pouze tmpfs a MySQL proxy. V lua si uděláte pravidlo aby SELECT  šel ze slave serveru s ramfs a všechny ostatní operace se prováděly na master serveru.
Na to musíte mít počítačového mága.

Nejlepším řešením je zkombinovat všechno.