sql >> Database >  >> RDS >> Mysql

Wat is het verschil tussen cachePrepStmts en useServerPrepStmts in MySQL JDBC Driver

Ten eerste is het belangrijk om onderscheid te maken tussen door de client en de server voorbereide verklaringen.

Door de klant opgestelde verklaringen

Door de klant opgestelde verklaringen zijn "geëmuleerde" voorbereide verklaringen. Dit betekent dat de tekenreeks van de SQL-instructie aan de clientzijde wordt getokeniseerd en dat eventuele tijdelijke aanduidingen worden vervangen door letterlijke waarden voordat de instructie naar de server wordt verzonden voor uitvoering. Bij elke uitvoering wordt een compleet SQL-statement naar de server gestuurd. U kunt het algemene logboek gebruiken om te onderzoeken hoe dit werkt. bijv.

de volgende code:

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

zou in het logboek verschijnen:

255 Query  select 42
255 Query  select 43

De "query" geeft aan dat, op protocolniveau, een COM_QUERY commando wordt verzonden met de volgende instructiereeks.

Op de server voorbereide verklaringen

Door de server voorbereide instructies zijn "echte" voorbereide instructies, wat betekent dat de vraagtekst naar de server wordt verzonden, geparseerd en tijdelijke aanduiding- en resultaatinformatie wordt teruggestuurd naar de client. Dit krijg je als je useServerPrepStmts=true instelt . De instructiereeks wordt slechts één keer naar de server verzonden met een COM_STMT_PREPARE bel (gedocumenteerde hier ). Elke uitvoering wordt uitgevoerd door het verzenden van een COM_STMT_EXECUTE met de voorbereide instructiehandle en de letterlijke waarden om de tijdelijke aanduidingen te vervangen.

In tegenstelling tot het door de klant voorbereide voorbeeld, kunnen we een soortgelijk codeblok gebruiken (maar deze keer met door de server voorbereide instructies ingeschakeld):

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

En het logboek zou laten zien:

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

U kunt zien dat de instructie is voorbereid voordat deze wordt uitgevoerd. Het logboek doet ons een plezier en toont de volledige verklaring voor de uitvoering, maar in feite worden alleen de tijdelijke waarden voor elke uitvoering van de client naar de server verzonden.

Voorbereide verklaringen in cache opslaan

Veel verbindingspools slaan voorbereide instructies op in de cache voor gebruik van een verbinding, wat betekent dat als u conn.prepareStatement("select ?") aanroept , retourneert het dezelfde PreparedStatement instantie op opeenvolgende aanroepen met dezelfde instructiereeks. Dit is handig om te voorkomen dat dezelfde string herhaaldelijk op de server wordt voorbereid wanneer verbindingen tussen transacties worden teruggestuurd naar de pool.

De MySQL JDBC-optie cachePrepStmts zal op deze manier voorbereide verklaringen in de cache opslaan (zowel door de client als de server voorbereide verklaringen) en de "bereidbaarheid" van een verklaring in de cache opslaan. Er zijn enkele instructies in MySQL die niet aan de serverzijde kunnen worden voorbereid. De chauffeur zal proberen een verklaring op de server voor te bereiden als hij denkt dat dit mogelijk is en, als de voorbereiding mislukt, terugvallen op een door de klant opgestelde verklaring. Deze controle is duur omdat er een retourtje naar de server nodig is. De optie slaat ook het resultaat van deze controle op in de cache.

Ik hoop dat dit helpt.




  1. PHP Database Dump Script - zijn er problemen?

  2. Wanneer een index toevoegen aan een SQL-tabelveld (MySQL)?

  3. Converteer String ISO-8601-datum naar het tijdstempelgegevenstype van orakel

  4. MySQL verwijdert geen records