Cache dat z dotazů
- Mas3r
- Člen | 116
Když jsem si teď projížděl SQL log z dibi, tak jsem objevil, že při 1 životním cyklu mám například 11 dotazů, z toho 3 jsou úplně identické.
- Výběr kategorií pro menu eshopu
- Výběr kategorií pro podkategorie v katalogu
- Výběr kategorií pro vyhledávač
Tak mě napadlo, že když to vraci úpně stejná data, tak by se ty data mohly někam ukládat a chytře rozšířená třída DibiTable by specifické dotazy mohla ukládat do cache a klíčem by byl samotný dotaz. Myslíte, že to má cenu? Když 1 dotaz trvá 0.5ms?
- Jan Tvrdík
- Nette guru | 2595
Mas3r napsal(a):
No je to dotaz nekde na pomezi Nette/Dibi… Zoptimalizovat: Právě nevím jak. Když ve 3 různých komponentách potřebuješ stejná data, tak je mezi těmi komponentami jednoduše sdílet?
Komponenta požádá o data model a ten si je zapamatuje i pro další komponenty.
- Honza Marek
- Člen | 1664
Myslim, že to DibiDataSource by mohlo pomoct. Ale když trváš na tom, že stejnej dotaz musí vracet více metod, tak nevim.
- onge
- Člen | 53
Pokud pustis po sobe 3 identicke dotazky, tak si je interne cachuje uz SQL server (alespon MySQL to tak dela). Respektive nacachuje se dotaz, ne vysledky, ale pokud nectes tisice zaznamu, tak to stejne nevrati o moc pomaleji, nez by trvalo nejake cachovani v PHP (a nejspis sezere min pameti), protoze ten dotaz uz je zpracovany a rovnou se spousti.
Pokud tahas neco vetsiho, co budes potrebovat tak bych si ten vysledek proste ulozil do nejake promene a bral to z toho, nebo napsal metodu tak, aby to nacetla pouze jednou a ulozila. Kazdopadne resit tohle tak, ze by se cachovali vsechny SQL dotazy by dle meho nazoru neprineslo nic dobreho, spis by tim mohla zatez dokonce narust.
- kravčo
- Člen | 721
Mas3r napsal(a):
Když jsem si teď projížděl SQL log z dibi, tak jsem objevil, že při 1 životním cyklu mám například 11 dotazů, z toho 3 jsou úplně identické.
- Výběr kategorií pro menu eshopu
- Výběr kategorií pro podkategorie v katalogu
- Výběr kategorií pro vyhledávač
Tak mě napadlo, že když to vraci úpně stejná data, tak by se ty data mohly někam ukládat a chytře rozšířená třída DibiTable by specifické dotazy mohla ukládat do cache a klíčem by byl samotný dotaz. Myslíte, že to má cenu? Když 1 dotaz trvá 0.5ms?
Možno by bolo na mieste optimalizovať radšej návrh, ako kešovať dopyty, ktoré sa vykonajú viackrát. Čiže radšej nerozmýšľať, ako tie dopyty nakešovať, rozmýšľať prečo tam tie tri rovnaké dopyty mám a či mi nestačí len jeden vhodne umiestnený…
Jan Tvrdík napsal(a):
Komponenta požádá o data model a ten si je zapamatuje i pro další komponenty.
Toto je jeden z možných spôsobov, ako to vyriešiť, dáta sú potrebné na viacerých miestach, ťahajú sa z modelu a model si výsledok po prvom vyžiadaní zapamätá, teda pri ďalších požiadavkach na dáta neposiela dopyt na databázu, ale vráti zapamätaný výsledok.
- pmg
- Člen | 372
Pro použití jedné instance modelu je užitečné ho registrovat jako službu. Je to lepší než používat singleton, protože o použití sdílené instance rozhodne sama komponenta.
Environment::getServiceLocator()->addService(new Model($connection));
// v komponentě
$model = Environment::getService('Model');
- phx
- Člen | 651
Osobne model pouzivam jako jedinacka skrz celou aplikaci. Navic se mi ukazuje, ze pri jednoduchych dotazech e nacteni z DB zanedbatelne oproti samotnemu vykresleni napr do menu ci roletky:)
Osobne bych spise uvital kesovani napric requesty na app. Pri kazdem requestu nactiam menu, info o uzivateli a spol. Coz by teoreticky stacilo nacist pouze 1× pri prihlaseni. Otazka zni zda ma cenu takova data drzet v session. Zda by to melo vyznam. (vykonostni)
- Jod
- Člen | 701
pmg, budem asi musieť použiť tie service, kôli Acl, aby som tam dostal model.
phx, info o užívateľovi si ukladám do session a menu by som ukladal do
cache v modelu. To je lepšie asi oblúžiť ručne než by to malo robiť
nette zateba. Na toto mám jednu otázku.
Keď z modelu vraciam datasource a chcem dáta cachovať priamo v modeli a
vracať buď datasource, alebo datasource aj s dátami, alebo nejakym spôsobom
cachované dáta..nejak mi nenapadá ako nato. Možno by bolo dobré mať (ak to
tam ešte neni) v datasouce udalosť onExecute, ktorá bude vraciať hodnoty
z databázy, resp. datasource aj s načítanými dátami (sender) a celý
object hodím do cache. Po načítani stránky zistím či objekt neni v cache,
ak je vrátim cachovaný object s už načítanými dátami. V tomto prípade
sa mi pozdáva aby si datasouce udržiaval dáta pčas svojej životnosti.
Ešte je tu možnosť používať cache helper v šablonách. Či to nebude jednoduchšie riešenie.
Ešte opravím tú registráciu service:
<?php
// mali by sme zadať service name ak nemáme len jeden model
Environment::getServiceLocator()->addService(new Model($connection), 'Model');
?>
Editoval Jod (22. 2. 2009 12:55)