2015-08-29 27 views
14

Il driver MySQL JDBC definisce queste due proprietà come:Qual è la differenza tra cachePrepStmts e useServerPrepStmts in MySQL JDBC driver

  • useServerPrepStmts - istruzioni preparate utilizzo sul lato server se il server li sostiene?

  • cachePrepStmts - Nel caso la cache pilota la fase di analisi dei PreparedStatements di lato client istruzioni preparate, il "check" per idoneità del lato server preparate e server-side preparato dichiarazioni stesse?

è la dichiarazione preparata sul lato client un modo per riutilizzare gli oggetti PreparedStatements?

Se è abilitato lo useServerPrepStmts, cosa viene memorizzato nella cache, poiché MySQL non dispone di execution plan cache anyway?

risposta

34

In primo luogo, è importante distinguere tra istruzioni preparate client e server.

client prepared statement

client preparati dichiarazioni sono "emulate" istruzioni preparate. Ciò significa che la stringa dell'istruzione SQL viene tokenizzata sul lato client e qualsiasi segnaposto viene sostituito con valori letterali prima di inviare l'istruzione al server per l'esecuzione. Una dichiarazione SQL completa viene inviata al server ad ogni esecuzione. È possibile utilizzare il registro generale per verificare come funziona. per esempio.

il seguente codice:

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

avrebbe mostrato nel registro:

255 Query select 42 
255 Query select 43 

Il "query" indica che, a livello di protocollo, un comando COM_QUERY viene inviato con la stringa seguente istruzione .

Server prepared statement

Server preparati dichiarazioni sono "veri" istruzioni preparate che significa che il testo della query viene inviata al server, analizzato, e segnaposto e dei risultati Informazione viene restituito al client. Questo è ciò che ottieni impostando useServerPrepStmts=true. La stringa di istruzione viene sempre inviata al server una sola volta con una chiamata COM_STMT_PREPARE (documentata here). Ogni esecuzione viene eseguita inviando un COM_STMT_EXECUTE con l'handle di istruzione preparato e i valori letterali per sostituire i segnaposto.

in contrasto con l'esempio cliente preparata, siamo in grado di utilizzare un blocco simile di codice (ma questa volta con le istruzioni preparate server abilitato):

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

E il registro sarebbe mostrare:

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

Si può vedere che la dichiarazione viene preparata prima di essere eseguita. Il log ci sta facendo un favore e mostra la dichiarazione completa per l'esecuzione ma, in realtà, solo i valori segnaposto vengono inviati da client a server per ogni esecuzione.

memorizzazione nella cache istruzioni preparate

Molti pool di connessioni nella cache istruzioni preparate attraverso usi di una connessione che significa che se si chiama conn.prepareStatement("select ?"), tornerà lo stesso PreparedStatement istanza su chiamate successive con la stessa stringa dichiarazione. Ciò è utile per evitare di preparare ripetutamente la stessa stringa sul server quando le connessioni vengono restituite al pool tra le transazioni.

L'opzione JDBC MySQL cachePrepStmts memorizza nella cache le istruzioni preparate in questo modo (sia le istruzioni preparate dal client e dal server) sia memorizza nella cache la "preparabilità" di una dichiarazione. Ci sono alcune affermazioni in MySQL che non sono preparabili dal lato server. Il driver proverà a preparare una dichiarazione sul server se crede che sia possibile e, se la preparazione fallisce, ricade su una dichiarazione preparata dal cliente. Questo controllo è costoso a causa di un round trip sul server. L'opzione memorizzerà inoltre il risultato di questo controllo nella cache.

Spero che questo aiuti.

+1

Ottima spiegazione. Non ero a conoscenza del fatto che i valori di bind delle istruzioni lato client sono sostituiti sul lato client prima di essere inviati al server. –

+0

Sembra che la proprietà useServerPrepStmts sia disabilitata per impostazione predefinita, ovvero impostata su false, il che significa in pratica che la maggior parte delle applicazioni è automaticamente impostata su PS lato client? Inoltre, che senso/vantaggio fornisce dato che cachePrepStmts è anche disabilitato di default? – sactiw