sql >> Databasteknik >  >> RDS >> Mysql

Vad är skillnaden mellan cachePrepStmts och useServerPrepStmts i MySQL JDBC Driver

Först är det viktigt att skilja mellan klient- och serverförberedda uttalanden.

Klientförberedda uttalanden

Klientförberedda uttalanden är "emulerade" förberedda uttalanden. Detta innebär att SQL-satssträngen tokeniseras på klientsidan och eventuella platshållare ersätts med bokstavliga värden innan satsen skickas till servern för exekvering. En komplett SQL-sats skickas till servern vid varje körning. Du kan använda den allmänna loggen för att undersöka hur detta fungerar. t.ex.

följande kod:

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

skulle visa i loggen:

255 Query  select 42
255 Query  select 43

"Frågan" indikerar att, på protokollnivå, en COM_QUERY kommandot skickas med satssträngen efter.

Serverförberedda uttalanden

Serverförberedda påståenden är "sanna" förberedda påståenden, vilket betyder att frågetexten skickas till servern, analyseras och platshållare och resultatinformation returneras till klienten. Detta är vad du får när du ställer in useServerPrepStmts=true . Uttryckssträngen skickas bara en gång till servern med en COM_STMT_PREPARE samtal (dokumenterat här ). Varje körning utförs genom att skicka en COM_STMT_EXECUTE med det förberedda uttalshandtaget och de bokstavliga värdena för att ersätta platshållarna.

Som kontrast till det klientförberedda exemplet kan vi använda ett liknande kodblock (men den här gången med serverförberedda satser aktiverade):

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

Och loggen skulle visa:

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

Du kan se att uttalandet är förberett innan det körs. Loggen gör oss en tjänst och visar hela uttalandet för körningen, men i själva verket skickas endast platshållarvärdena från klient till server för varje körning.

Cacha förberedda uttalanden

Många anslutningspooler cachelagrar förberedda uttalanden över användningar av en anslutning, vilket innebär att om du anropar conn.prepareStatement("select ?") , kommer det att returnera samma PreparedStatement instans på successiva anrop med samma uttalande sträng. Detta är användbart för att undvika att förbereda samma sträng på servern upprepade gånger när anslutningar returneras till poolen mellan transaktioner.

MySQL JDBC-alternativet cachePrepStmts kommer att cache förberedda satser på detta sätt (både klient- och serverförberedda satser) samt cachelagra "förberedbarheten" för en sats. Det finns vissa uttalanden i MySQL som inte går att förbereda på serversidan. Drivrutinen kommer att försöka förbereda en sats på servern om den tror att det är möjligt och, om prepareringen misslyckas, falla tillbaka till en klientförberedd sats. Denna check är dyr på grund av att den kräver en tur och retur till servern. Alternativet cachelagrar också resultatet av denna kontroll.

Hoppas detta hjälper.




  1. Dåliga vanor:Undviker NULL i SQL Server

  2. Inre Sammanfogning av tre bord

  3. Kan vi omfördela Oracle tools.jar?

  4. Så här åtgärdar du ett fel för överskriden låsväntetid i MySQL