4.26 Proč je můj dotaz pomalejší, když je spuštěn jako předpřipravený dotaz?

Z PostgreSQL
Skočit na navigaci Skočit na vyhledávání

V případě, že během přípravy (plánování dotazu) jsou k dispozici všechny parametry dotazu způsobí, že optimalizátor může, na základě statistik, zvolit optimální způsob zpracování dotazu. Pokud se může čekat, že kritériím dotazu vyhoví několik málo řádků, použije se index, který ovšem není výhodný, pokud by kritériím vyhověla velké množství řádků z tabulky, kdy je naopak vhodnější sekvenční čtení tabulky.

V případě předpřipravených dotazů (prepared statements), optimalizátor PostgreSQL nemá k dispozici parametry dotazu (když se sestavuje prováděcí plán). Zkouší se tedy sestavit "bezpečný" plán, který by měl dostatečně dobrý bez ohledu na skutečně použité parametry. V některých situacích, když v kritériích dotazu jsou hodnoty, které se vyskytují extrémně často nebo téměř vůbec, tento bezpečný plán nemusí být optimální.

Pokud si myslíte, že to je Váš případ, tak se podívejte na prováděcí plán dotazu (zobrazí jej příkaz EXPLAIN) rychlých a pomalých dotazů. Podívejte se jestli se výstup z EXPLAIN SELECT a EXPLAIN EXECUTE nějak významně liší.

Tento problém se většinou vyskytuje v souvislosti s použitím předpřipravených dotazů jako ochrany proti SQL injektáži - spíše než v použití předpřipravených dotazů jako optimalizace (úspory času z důvodu plánování dotazu) u často prováděných dotazů. Řešením mohou být předpřipravené dotazy na klientské straně, v případě, že používají rozhraní (driver), které tuto funkcionalitu podporuje (např. JDBC).

V tuto chvíli PostgreSQL neposkytuje způsob jak přeplánovat předpřipravené dotazy pro nějakým způsobem specifickou kombinaci hodnot parametrů. Někdy může pomoci aktualizace statistik (příkaz ANALYZE) - někdy ovšem není jiné řešení a předpřipravené dotazy nelze použít - nebo se smířit s horším výkonem v některých situacích.