sql >> Databáze >  >> RDS >> Mysql

Jaký je rozdíl mezi cachePrepStmts a useServerPrepStmts v MySQL JDBC Driver

Nejprve je důležité rozlišovat mezi příkazy připravenými klientem a serverem.

Prohlášení připravená klientem

Klientem připravené výpisy jsou „emulované“ připravené výpisy. To znamená, že řetězec příkazu SQL je tokenizován na straně klienta a všechny zástupné symboly jsou nahrazeny doslovnými hodnotami před odesláním příkazu na server k provedení. Při každém spuštění je na server odeslán úplný příkaz SQL. Chcete-li zjistit, jak to funguje, můžete použít obecný protokol. např.

následující kód:

ps=conn.prepareStatement("select ?")
ps.setInt(1, 42)
ps.executeQuery()
ps.setInt(1, 43)
ps.executeQuery()

se zobrazí v protokolu:

255 Query  select 42
255 Query  select 43

"Dotaz" označuje, že na úrovni protokolu COM_QUERY příkaz je odeslán s následujícím řetězcem příkazu.

Prohlášení připravená serverem

Serverem připravené příkazy jsou "pravdivé" připravené příkazy, což znamená, že text dotazu je odeslán na server, analyzován a zástupný symbol a informace o výsledku jsou vráceny klientovi. To je to, co získáte, když nastavíte useServerPrepStmts=true . Řetězec příkazu je vždy odeslán na server pouze jednou s COM_STMT_PREPARE hovor (zdokumentováno zde ). Každé provedení se provádí odesláním COM_STMT_EXECUTE s připraveným popisovačem příkazu a doslovnými hodnotami, které mají nahradit zástupné symboly.

Na rozdíl od příkladu připraveného klientem můžeme použít podobný blok kódu (tentokrát se zapnutými příkazy připravenými serverem):

ps2=conn2.prepareStatement("select ?")
ps2.setInt(1, 42)
ps2.executeQuery()
ps2.setInt(1, 43)
ps2.executeQuery()

A protokol by ukázal:

254 Prepare    select ?
254 Execute    select 42
254 Execute    select 43

Můžete vidět, že příkaz je připraven před provedením. Protokol nám dělá laskavost a zobrazuje kompletní příkaz pro provedení, ale ve skutečnosti jsou z klienta na server pro každé provedení odesílány pouze zástupné hodnoty.

Ukládání připravených výpisů do mezipaměti

Mnoho fondů připojení ukládá do mezipaměti připravené příkazy pro různá použití připojení, což znamená, že pokud zavoláte conn.prepareStatement("select ?") , vrátí stejný PreparedStatement instance na po sobě jdoucích voláních se stejným řetězcem příkazů. To je užitečné, abyste se vyhnuli opakované přípravě stejného řetězce na serveru, když se spojení mezi transakcemi vrací do fondu.

Možnost MySQL JDBC cachePrepStmts bude tímto způsobem ukládat do mezipaměti připravené příkazy (příkazy připravené klientem i serverem) a také ukládat do mezipaměti "připravitelnost" příkazu. V MySQL jsou některé příkazy, které nelze připravit na straně serveru. Ovladač se pokusí připravit výpis na serveru, pokud se domnívá, že je to možné, a pokud se příprava nezdaří, vrátí se k výpisu připravenému klientem. Tato kontrola je drahá, protože vyžaduje zpáteční cestu k serveru. Tato možnost také uloží výsledek této kontroly do mezipaměti.

Doufám, že to pomůže.




  1. 2 způsoby, jak vrátit řádky, které neobsahují číselné hodnoty v Oracle

  2. Záměna s Oracle CONNECT BY

  3. 2 způsoby, jak zjistit, zda se v instanci serveru SQL Server stále používají zastaralé funkce

  4. Jak vytvořit dynamický dotaz navázáním parametrů v node.js-sql?