Bylo pro mě nemilým překvapením, když jsem se dozvěděl, že funkce mysql_query od MySQL serveru spolu s položením dotazu také získá všechna vrácená data a uloží je do paměti. Funkce mysql_fetch_assoc a podobné pak už s MySQL serverem nekomunikují a data předávají z paměti. Pokud běží MySQL server na jiném počítači, je toto chování samozřejmě žádoucí, vzdálená komunikace kvůli každému řádku by zbytečně zdržovala. Pokud ale MySQL server běží na stejném počítači jako webový server, tak může být zatížení serveru spojené se zaplněním paměti výraznější než režie komunikace s databází. Pro položení SQL dotazu bez ukládání výsledků do paměti slouží funkce mysql_unbuffered_query. Tato funkce se používá stejně jako mysql_query, ale má některá omezení – především nelze zjistit počet vrácených řádek a lze pracovat jen s posledním položeným dotazem, takže ji rozhodně není možné použít jako univerzální náhradu. Použití je tedy vhodné při splnění těchto podmínek:
Po pravdě řečeno, takové podmínky jsou u webových aplikací splněny málokdy. Lepší je tedy navrhovat dotazy tak, aby se nevýhoda funkce mysql_query naplno neprojevila a přenášet jen ta data, která opravdu budeme potřebovat:
<?php // pokud tabulka stranky obsahuje např. i obsah stránky, je lepší se vyhnout SELECT * $result = mysql_query("SELECT id, nadpis FROM stranky"); while ($row = mysql_fetch_assoc($result)) { echo "<a href='?id=$row[id]'>" . htmlspecialchars($row["nadpis"]) . "</a>\n"; } // pokud bude potřeba většina dat, je možné SELECT * použít $row = mysql_fetch_assoc(mysql_query("SELECT * FROM stranky WHERE id = " . intval($_GET["id"]))); echo "<h1>$row[nadpis]</h1>\n$row[stranka]"; // pokud nebudeme potřebovat všechny řádky, je vhodné použít LIMIT $result = mysql_query("SELECT * FROM vyrobky ORDER BY nazev LIMIT 20"); ?>
Filtrování dat je samozřejmě záhodno dělat rovněž na straně databáze pomocí WHERE, přenášení do PHP a filtrování až ve skriptu je zbytečně pomalé a náročné na paměť.
Přijďte si o tomto tématu popovídat na školení Výkonnost webových aplikací.
Diskuse je zrušena z důvodu spamu.