ActiveRow::update() bez znovunačtení dat
- PVD
- Člen | 20
Používám ActiveRow::update()
metodu pro úpravu jedné
hodnoty řádku. Řádek (resp. tuto upravenou hodnotu) již dále nepotřebuji.
Zarazilo mě, když jsem díky Tracy zjistil, že se po update provede select do
db na daný řádek a to dokonce na všechny sloupce, nejen ten upravený.
Hledal jsem příčinu (ve svém kódu) a pak se podíval do
\Nette\Database\Table\ActiveRow
, kde jsem zjistil, že
update()
to znovu obnovení vyvolává.
Když jsem hledal na internetu, většinou se řešil (dříve) opačný
problém:
https://forum.nette.org/…-do-databaze
Na githubu jsem zjistil, že se to objevilo v jedné z úprav:
https://github.com/…0e5f860fa905
Jsem v Nette začátečník a nechci do něho zasahovat, ale není lepší dát toto znovunačtení jako možnost, třeba pomocí parametru?
V mém případě provedu update a rovnou přesměrování/vyjímku. Dál s řádkem nepracuji. Proč musím mít znovu zbytečně další dotaz do db?
Vím, že mohu udělat přímý příkaz
$database->query('UPDATE ... SET ? WHERE id=?', $data, $id);
,
ale když už je povedené řešení pomocí ActiveRow::update()
,
proč ho nepoužít?
P.S.: Počet dotazů u mého projektu skutečně řešit musím.
- Mysteria
- Člen | 797
Osobně mě to taky před časem vadilo, ale zjistil jsem, že jeden dotaz podle primárního klíče je pravdu zanedbatelná položka (řádově setiny až tisíciny milisekundy).
A proč to tak je? Předpokládám, že proto, že v 90% jsou ty hodnoty využity, například jenom pro prostou informaci typu Položka XYZ byla úspěšně upravena.
- PVD
- Člen | 20
Osobně mě to taky před časem vadilo, ale zjistil jsem, že jeden dotaz podle primárního klíče je pravdu zanedbatelná položka (řádově setiny až tisíciny milisekundy).
V mém případě je to 20ms (localhost), ale jde mi hlavně o princip a jak říkám, řeším úsporu všude.
A proč to tak je? Předpokládám, že proto, že v 90% jsou ty hodnoty využity, například jenom pro prostou informaci typu Položka XYZ byla úspěšně upravena.
Ano, ale mohl by být parametr výchozí true, kterým by šlo dané chování snadno změnit (vynechat část kódu, úspora všude).
- Mysteria
- Člen | 797
Localhost neřeším, tam mám běžně pro 20 dotazů hodnoty okolo 200ms a pak na ostrém serveru jsem okolo 1ms. :) Důležitý je, jak to pojde na provozu.
Ano, ale mohl by být parametr výchozí true, kterým by šlo dané chování snadno změnit (vynechat část kódu, úspora všude).
Jo, to by šlo. :)
- David Grudl
- Nette Core | 8239
Proč se to neudělá tak, že data se načtou, až když se k ním poprvé přistoupí?
- PVD
- Člen | 20
David Grudl napsal(a):
Proč se to neudělá tak, že data se načtou, až když se k ním poprvé přistoupí?
Nerozumím, mám udělat update
jinak, nebo je to
otázka návrh jak upravit to znovunačtení uvnitř
update
funkce? Určitě by stačilo, kdyby se načetla pouze tehdy,
když se s nimi bude dále pracovat. Pokud je to takto míněno, tak
souhlas.
Editoval PVD (11. 7. 2015 19:14)
- PVD
- Člen | 20
Přidám jeden čerstvý příklad, budu rád, pokud mě někdo upozorní,
že to dělám nevhodně.
Mám SessionManager
, který obsluhuje tabulku, ve které se
uchovává PHPSESSID
, ip adresa aj. Při přihlášení se
vytvoří záznam. Dále s ním (záznamem) však nikde nepracuji.
Z nynějšího chování update()
však vyplývá, že se mi
uložený řádek rovnou načetl z db. Zbytečně.
Edit: tohle je vlastně insert, ale i tam by to nemuselo být povinné…
Editoval PVD (12. 7. 2015 21:41)
- PVD
- Člen | 20
Jan Tvrdík napsal(a):
@PVD Co takhle volat ten update nad Selection a ne nad ActiveRow?
To mohu, ale je něco nelogického či nesprávného na tom, že chci konkrétní řádek, který se používá v celé metodě, rovnou upravit? Proč bych měl pracovat se selection, když už jasně konkrétní řádek mám a ten chci upravit? Třeba uvažuju špatně, nevím.