Systém komponent a omezení počtu SQL dotazů
- Kcko
- Člen | 470
Ahoj,
hloubám nad touto věcí.
- Jedna komponenta zobrazuje cosi.
- Komponenta potřebuje data z DB a pro zjednodušení ji stačí udělat
dotaz
SELECT * FROM static_content where id = $id
. - Komponent může být na dané stránce X, různě rozložené (hlavička webu, střed, patička …)
Co chci? Aby když na stránce vykreslím 10 komponent tohoto typu, aby se
nevykonalo 10× dotazů s různými id ale jeden dotaz
s klauzulí WHERE id IN (1,2,3... 10)
Zatím mě napadá mít ještě jednu nadřazenou kontrolku (něco jako „dohližitel“), do které dané kontrolky na dané stránce zaregistruji a pak na konci životního cyklu v konkrétním presenteru jim data donačtu.
Akorát se mi nelíbí interakce s presenterem a taky přesně nevím, do jaké akce životního cyklusu to dát, pravděpodobně beforeRender.
Nemá někdo nějaký nápad jak to elegantně vyřešit bez nějaké šílené objektové obludnosti?
- Phalanx
- Člen | 310
Můžeš obalit dotazy cache – https://doc.nette.org/cs/caching
Případně i celé komponenty…
- ZahorskyJan
- Člen | 59
Pokud je to 10 komponent na jedne strance a potrebuji to stejne, tak jim to predavame do tovarny jako vstupni parametr a je to priznana zavislost. U nas priklad: detail nejakeho zaznamu ma X komponent a kazde komponente do tovarny jde entita toho zaznamu. Bud pouzije jen tu entitu (0 dalsich dotazu do DB) nebo si vytahne jina souvisejici data. Druha moznost je sluzba/manager, ktera pri nacitani ty data cachuje do interni promenne pri prvnim nacteni. Tzn. dalsi nacteni jsou uz z interni promenne (0 opakujicich se dotazu). Vyhoda tady te sluzby je, ze neresis zivotni cyklus. Proste kdo ji zavola prvni ten polozi dotaz a ostatni uz nic. Nette/cache je na ti vetsinou zbytecna, musis resit invalidaci. Tady ta interni promenna plati jen na ten jeden beh/request.
- Kcko
- Člen | 470
@ZahorskyJan
S tebou popisovaných řešení se žádné nehodí.
- Je to komponenta s nějakým ID, takže jí žádnou smysluplnou entitu s daty nepřidám, komponenta si je má zjištovat sama.
A pokud si ty data tahá sama, tak jsme u toho co dělat nechci. 10 komponent = 10 dotazů.
- Služba / Manager, o tom se musí nějak dozvědět, jaké komponenty jsou na stránce. A už jsme u toho způsobu co mám v hlavě, ale pořád to není to pravé ořechové co chci, tj. to, že si nějaká dozorovací „observerve“ komponenta ty svoje „děti“ zaregistruje a pak jim na konci životního cyklu (už zná jejich ID) vytáhne a doplní data z DB.
A jinak co se týká kešování per request, to že by to zjistila první komponenta na stránce je taky k ničemu. Ta o svých kámoších podobného typu vůbec neví, neví tedy jaká ID má zjistit.
Chci mít prostě na stránce X komponent jednoduchého typu, každá pro svoje vykreslení potřebuje jiný řádek z DB, vzájemně o sobě neví a nechce se mi vymýšlet systém, který je bude nějakým způsobem registrovat / monitorovat a pak jim někde životního cyklu doplnňovat data, ale zatím je to to jediné smysluplné co mě napadá.
Editoval Kcko (7. 2. 2020 23:31)
- ZahorskyJan
- Člen | 59
@Kcko rozumim. Spatne jsem z dotazu, ze kazda ta komponenta ma jine zaznamy.
Pokud ty ID pro kazdou komponentu znas dopredu (podle ceho ho ty komponenty rozhoduji?), tak si udelej tu sluzbu s interni pameti, nacti jednim dotazem vsechny radky a uloz si hodnoty do pole, kde klic je ID. Z komponent pak volej sluzbu, aby ti vratila zaznam podle ID. Sahne do pameti a vrati. Muze byt fallback, kdyby se nenaslo, ze si dotaz polozi.
Pak je otazka, jestli 10 dotazu podle primarniho klice/indexu je opravdu problem a stoji za optimalizaci.
- Kcko
- Člen | 470
@ZahorskyJan
Rozumím, jediné co se může stát, že budu mít předpřipravený seznam komponent, které na stránce chci použít a pak třeba jednu – dvě z nějakého důvodu nebudu potřebovat (prostě ji v latte šabloně dočasně zakomentuji).
A hledám způsob jak sebrat IDčka pouze aktivních komponent na stránce a dodat jim data.
A to že se komponenta chce vykreslovat zjistím kde a jak? v render metodě? v attached? Tam by měla proběhnout nějaká kontrola a pak jí teprve dodat data, ale ty už musí být přednačtená onou servisou dopředu :-)
Jak tedy tohle vyřešit?
- Martk
- Člen | 661
To co by sis představoval nejde.
Že se komponenta použije zjistíš až v latte souboru, kde se provede
kód {control foo}
, to už je velmi pozdě a teprve v tuto chvíli
se zavolá createComponentFoo. Shrnu to: teprve až se latte celé vyrendruje,
tak znáš všechny komponenty.
Editoval Martk (8. 2. 2020 9:04)