sql >> Databáze >  >> RDS >> PostgreSQL

Jaká je životnost příkazu připraveného na straně serveru PostgreSQL

Takže vaše otázka se nakonec scvrkává na „jak java.sql.PreparedStatement hraje s PostgreSQL." Viz odpověď na závěr „jak se to hraje s plány připravenými na serveru".

Zde je odpověď:to závisí na ovladači JDBC, který používáte.

TL;DR :v moderních ovladačích serverem připravený příkaz žije, dokud spojení nezemře nebo dokud není příkaz vyřazen jiným (pravidelné vyřazení LRU).

Poznámka:Server PostgreSQL nemůže sdílet připravený příkaz mezi databázovými připojeními, takže nejlepší ovladač JDBC, který může udělat, je ponechat plán v mezipaměti pro každé připojení.

Poznámka:Specifikace JDBC nařizuje použití ?, ? pro zástupné symboly vazby, zatímco server chce $1, $2 takže ovladače JDBC ukládají do mezipaměti také takzvané analyzované texty SQL.

Existují dva známé ovladače JDBC:pgjdbc a pgjdbc-ng

pgjdbc

https://github.com/pgjdbc/pgjdbc

Od pgjdbc 9.4-1202 při použití PreparedStatement automaticky ukládá plány na straně serveru do mezipaměti .Poznámka:příkazy se ukládají do mezipaměti, i když close() PreparedStatement .Abyste se dostali k přípravě na straně serveru, musíte provést dotaz 5krát (to lze nakonfigurovat pomocí prepareThreshold ).

V současné době je mezipaměť implementována pro každé připojení. Ve výchozím nastavení pgjdbc ukládá do mezipaměti 256 (preparedStatementCacheQueries ) dotazy a až preparedStatementCacheSizeMiB dotazů. Toto je konzervativní nastavení, takže jej možná budete chtít upravit. Viz dokumentace pro popis vlastností. Mezipaměť obsahuje jak analyzované, tak serverem připravené příkazy.

problém s githubem:https://github.com/pgjdbc/pgjdbc/pull/319

pgjdbc-ng

https://github.com/impossibl/pgjdbc-ng

Nejsem na pgjdbc-ng, ale vypadá to, že provádí obě analýzy (výchozí velikost mezipaměti je 250 dotazy) a příprava serveru (výchozí velikost mezipaměti je /a> dotazy). Podpora příkazů připravených na straně serveru byla spuštěna 24. února 2014, takže pokud používáte novější verzi, můžete získat ukládání příkazů do mezipaměti.

Poznámka:Pokud omylem použijete velmi dlouhé dotazy, můžete kliknout na OutOfMemory protože pgjdbc-ng nemůže vyřadit položky na základě počtu zadržených bajtů.

Mezipaměť je pro jednotlivá připojení, takže se transparentně používá, i když příkazy zavřete.

Nemohu říci mnoho o výkonu pgjdbc-ng, i když od poslední doby, kdy jsem se na něj pokusil hodit jmh, selhal až na náhodné výjimky.

problém s githubem:https://github.com/impossibl/pgjdbc-ng/pull/ 69

Plány připravené serverem

PostgreSQL má PREPARE a DEALLOCATE příkazy, které odkazují na příkaz při odesílání EXEC přes drát. Optimalizuje dvě věci:

  1. Při použití PREPARE d (jinými slovy serverem připravený), klient nemusí posílat text dotazu znovu a znovu. Odešle pouze krátký název dotazu a hodnoty pro proměnné vazby.
  2. Od verze 9.2 se databáze stále pokouší přeplánovat prvních několik spuštění dotazu. Dělá to proto, aby vyzkoušelo, zda dotaz potřebuje více plánů nebo zda je obecný plán dostatečně dobrý. Nakonec (okamžitě, pokud dotaz nemá žádné parametry), databáze může přejít na obecný plán .
  3. Od 12. roku existuje nastavení, které vynutí provádění VŠECH příkazů připravených na serveru s obecnými nebo vlastními plány:režim_plánovací_mezipaměti =auto | force_custom_plan | force_generic_plan

Jinými slovy PreparedStatement optimalizuje jak analýzu dotazů na straně JDBC, tak plánování dotazů na straně databáze.

Více informací zde:http://blog.endpoint .com/2014/04/custom-plans-prepared-statements-in.html

Připravené příkazy v PL/pgSQL

Podle dokumentace se PostgreSQL ukládá do mezipaměti plány pro dotazy používané v PL/pgSQL. To se stane po několika spuštěních (3 nebo 5, nepamatuji si přesný práh), takže po vytvoření uložené procedury to může být trochu pomalé, ale pak se přepne na plány uložené v mezipaměti (za předpokladu, že databáze souhlasí s použitím obecného plánu pro konkrétní dotaz).

Jinými slovy, abyste dosáhli „plánů provádění uložených v mezipaměti“, musíte buď použít aktuální ovladač JDBC, nebo můžete všechny své dotazy zabalit do uložených procedur. Volání procedury se přeplánuje při každém spuštění, ale samotné volání je obvykle mnohem kratší než dotazy, které tvoří proceduru.



  1. MySQL LEFT JOIN pomocí MAX &GROUP BY na spojeném stole?

  2. Vložit seznam hodnot neodpovídá seznamu sloupců:1136 Počet sloupců neodpovídá počtu hodnot

  3. Jak nainstalovat MySQL Workbench na Ubuntu

  4. Včetně tabulek a schémat při výpisu sloupců identity v databázi SQL Server