Autor Zpráva
Dusan
Profil *
Cez $result = $conn->query('SELECT nazov FROM skuska') si vygenereujem result set.

Kam sa tento result set ulozi ?

Ak pouzijem sleep(30), za nim echo $result->fetchColumn() a v dobe sleepu zastavim sluzbu MySQL, vysledok cez fetchColumn() aj napriek tomu dostanem.

Z toho sa javi ako keby result set bol ulozeny mimo SQL, v nejakej docasnej cache.

Viete niekto ako to presne funguje a kam sa uklada result set vzhladom na volanie z PHP cez PDO ? Dik
pcmanik
Profil
Dusan:
Result set sa uloží do danej premennej result teda do RAM. Metóda fetchColumn sa už volá nad dátami ktoré boli vrátené z databázy a sú aktuálne uložené v premennej result.
Dusan
Profil *
Z dokumentacie som tiez pochopil, ze PDOstatement object (teda premenna $result) obsahuje result set.

Ale zda sa ze to tak nie je a obsahuje iba pouzity SQL statement.

memory_get_usage() po query() mi neukazuje ziadny narast vyuzitia RAM v ramci PHP.
Dusann
Profil
Nakoniec som sa k potrebným informáciám dopracoval: http://www.php.net/manual/en/mysqlinfo.concepts.buffering.php

Závisí to teda od atribútu PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, default je true.


Dusan:
memory_get_usage() po query() mi neukazuje ziadny narast vyuzitia RAM v ramci PHP


Neukazuje, pretože:
When using libmysqlclient as library PHP's memory limit won't count the memory used for result sets unless the data is fetched into PHP variables

Je škoda, ze v PHP dokumentácii v sekcii PDO::query nie je žiadna zmienka o buffered queries. Informácia PDO::query — Executes an SQL statement, returning a result set as a PDOStatement object je korektná na 50% keďže vrátenie result set zavisí od spomínaného atribútu. Človek potom stratí veľa času pretože info ktoré s tým súvisí sa nachádza niekde zakopané v úplne inej sekcii :-(
Dusann
Profil
Preštudoval som celkom dosť materiálov, ale stále nemám jasno v tomto:

Čo presne sa deje vrámci komunikácie PHP a MySQL a čo sa deje na strane MySQL, ak pošlem SELECT query a pracujem v režime unbuffered queries ?

Ak som pochopil správne, tak všeobecne SELECT od nejakého klienta vytvorí na serveri MySQL result set, ktorý je ihneď vrátený klientovi a ten si celý result set niekam uloží a procesuje sám. Na strane servera teda nevznikajú žiadne resources pre uloženie result set. V PHP by to teda malo fungovať v režime buffered queries.

Čo ale v prípade ak nechceme aby klient po SELECT query prijal result set, ale aby sa result set vytvoril na strane serveru a klient si mohol zo serveru fetchovat jednotlivé záznamy ?
Ak dobre chápem, tak v SQL je možné vytvoriť result-set na strane serveru bez toho, aby ho klient prijal, jedinou cestou - SQL procedúra alebo funkcia s kurzorom. Ak neexistuje ale iný spôsob, tak nerozumiem tomu ako to funguje v interakcii s PHP a PDO. Ide o to, že SQL procedúra prebieha ako celok a fetch cez kurzor prebieha vo vnútri procedúry: kurzor sa otvorí, vytvorí sa result set, záznamy sa fetchujú a kurzor sa uzavrie:

...
open curs;
fetch curs into col1,col2;
select capt,fil;
fetch curs into col1,col2;
select capt,fil;
close curs;
...

Ak mám teda v PHP nastavený režim unbuffered queries (result-set na strane MySQL) a volám:

$result = $conn->query('SELECT * FROM images');
// aký statement sa odošle do MySQL ? Ak by to bolo volanie SQL procedúry, result-set by sme už v tomto bode premiestnili do PHP a kurzor s jeho aktuálnou pozíciou v procedúre by sa uzavrel.

$result->fetch();
$result->fetch();
// cez tieto dve metódy ale fetchujeme záznamy z result-set ďalej => logika mi to nepoberá, takže otázka je ako je možné že v tomto bode sekvenčne fetchujeme jednotlivé záznamy z result-set ktorý by sa mal nachádzať na MySQL serveri ?

 $result->closeCursor();
// zatvárame kurzor - Ak úvodné query spustilo procedúru s kurzorom, tak kurzor je už predsa dávno uzavretý, keďže SQL procedúra beží naraz ako celok.

Je dosť možné, že niektoré veci ktoré tu popisujem som nepochopil správne a celé to funguje ináč.
Takže budem vďačný za korektné vysvetlenie, poprípade objasnenie, díky.
juriad
Profil
Asi takto, PHP se k mysql připojuje skrze nějakou knihovnu (mysql_, mysqli_, PDO), tato knihovna je napsaná v jazyku C a sama si hospodaří s pamětí. Limity, které používá PHP se jí netýkají.
Result-set je jen odkazem na C-čkovou proměnnou někde hluboko v té knihovně. Jelikož je result-set jen odkazem, nezabírá skoro žádné místo. S result-setem můžeš pracovat jen pomocí funkcí a metod té knihovny, nijak jinak. A některé z těch funkcí jsou zodpovědné za zkopírování hodnoty do skutečné PHP proměnné (to je třeba ta metoda fetch).

Buffered a unbuffered query se liší jen tím, zda databáze odešle data výsledku té knihovně. Výhoda buffered query je ta, že se šetří čas při komunikaci po síti, ale na druhou stranu, mohou se tahat zbytečná data.

Musíš prostě počítat s tím, že je tam ještě jedna vrstva navíc, ke které máš přístup jen pomocí funkcí, které exportuje do PHP.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: