Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Was ist der Unterschied zwischen cachePrepStmts und useServerPrepStmts im MySQL JDBC-Treiber

Zunächst ist es wichtig, zwischen vom Client und vom Server vorbereiteten Anweisungen zu unterscheiden.

Vom Kunden vorbereitete Erklärungen

Vom Client vorbereitete Anweisungen sind "emulierte" vorbereitete Anweisungen. Dies bedeutet, dass die SQL-Anweisungszeichenfolge auf der Clientseite in Tokens umgewandelt wird und alle Platzhalter durch Literalwerte ersetzt werden, bevor die Anweisung zur Ausführung an den Server gesendet wird. Bei jeder Ausführung wird eine vollständige SQL-Anweisung an den Server gesendet. Sie können das allgemeine Protokoll verwenden, um zu untersuchen, wie dies funktioniert. z. B.

folgenden Code:

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

würde im Log erscheinen:

255 Query  select 42
255 Query  select 43

Die "Abfrage" gibt an, dass auf Protokollebene ein COM_QUERY Der Befehl wird mit der folgenden Anweisungszeichenfolge gesendet.

Vom Server vorbereitete Anweisungen

Vom Server vorbereitete Anweisungen sind "wahre" vorbereitete Anweisungen, was bedeutet, dass der Abfragetext an den Server gesendet, analysiert und Platzhalter- und Ergebnisinformationen an den Client zurückgegeben werden. Das erhalten Sie, wenn Sie useServerPrepStmts=true setzen . Der Anweisungsstring wird immer nur einmal mit einem COM_STMT_PREPARE an den Server gesendet aufrufen (dokumentiert hier ). ). Jede Ausführung wird durch Senden eines COM_STMT_EXECUTE durchgeführt mit dem Handle der vorbereiteten Anweisung und den Literalwerten, die die Platzhalter ersetzen sollen.

Als Kontrast zum vom Client vorbereiteten Beispiel können wir einen ähnlichen Codeblock verwenden (jedoch dieses Mal mit aktivierten vom Server vorbereiteten Anweisungen):

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

Und das Protokoll würde zeigen:

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

Sie können sehen, dass die Anweisung vorbereitet wird, bevor sie ausgeführt wird. Das Protokoll tut uns einen Gefallen und zeigt die vollständige Anweisung für die Ausführung, aber tatsächlich werden nur die Platzhalterwerte für jede Ausführung vom Client zum Server gesendet.

Vorbereitete Anweisungen zwischenspeichern

Viele Verbindungspools speichern vorbereitete Anweisungen über die Verwendung einer Verbindung hinweg, was bedeutet, dass Sie conn.prepareStatement("select ?") aufrufen , wird dasselbe PreparedStatement zurückgegeben Instanz bei aufeinanderfolgenden Aufrufen mit derselben Anweisungszeichenfolge. Dies ist nützlich, um zu vermeiden, dass dieselbe Zeichenfolge wiederholt auf dem Server erstellt wird, wenn Verbindungen zwischen Transaktionen an den Pool zurückgegeben werden.

Die MySQL-JDBC-Option cachePrepStmts speichert vorbereitete Anweisungen auf diese Weise (sowohl vom Client als auch vom Server vorbereitete Anweisungen) sowie die "Vorbereitbarkeit" einer Anweisung. Es gibt einige Anweisungen in MySQL, die serverseitig nicht vorbereitet werden können. Der Treiber wird versuchen, eine Anweisung auf dem Server vorzubereiten, wenn er dies für möglich hält, und, wenn die Vorbereitung fehlschlägt, auf eine vom Client vorbereitete Anweisung zurückgreifen. Diese Prüfung ist teuer, da ein Roundtrip zum Server erforderlich ist. Die Option speichert auch das Ergebnis dieser Prüfung.

Hoffe das hilft.