Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jaka jest różnica między cachePrepStmts a useServerPrepStmts w sterowniku MySQL JDBC

Po pierwsze, ważne jest, aby odróżnić wyciągi przygotowane przez klienta i serwer.

Oświadczenia przygotowane przez klienta

Wyciągi przygotowane przez klienta są „emulowanymi” wyciągami przygotowanymi. Oznacza to, że ciąg instrukcji SQL jest tokenizowany po stronie klienta, a wszelkie symbole zastępcze są zastępowane wartościami dosłownymi przed wysłaniem instrukcji do serwera w celu wykonania. Kompletna instrukcja SQL jest wysyłana do serwera przy każdym wykonaniu. Możesz użyć dziennika ogólnego, aby sprawdzić, jak to działa. np.

następujący kod:

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

pokaże się w dzienniku:

255 Query  select 42
255 Query  select 43

„Zapytanie” wskazuje, że na poziomie protokołu COM_QUERY polecenie jest wysyłane z następującym ciągiem instrukcji.

Wyciągi przygotowane przez serwer

Przygotowane instrukcje serwera są „prawdziwymi” przygotowanymi instrukcjami, co oznacza, że ​​tekst zapytania jest wysyłany do serwera, analizowany, a informacje zastępcze i wyniki są zwracane do klienta. Oto, co otrzymujesz, ustawiając useServerPrepStmts=true . Ciąg instrukcji jest wysyłany do serwera tylko raz z kodem COM_STMT_PREPARE zadzwoń (udokumentowane tutaj ). Każde wykonanie jest wykonywane przez wysłanie COM_STMT_EXECUTE z przygotowanym uchwytem instrukcji i wartościami dosłownymi zastępującymi symbole zastępcze.

W przeciwieństwie do przykładu przygotowanego przez klienta, możemy użyć podobnego bloku kodu (ale tym razem z włączonymi instrukcjami przygotowanymi przez serwer):

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

A dziennik pokazywałby:

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

Widać, że instrukcja jest przygotowywana przed wykonaniem. Dziennik wyświadcza nam przysługę i pokazuje pełną instrukcję wykonania, ale w rzeczywistości tylko wartości zastępcze są wysyłane od klienta do serwera dla każdego wykonania.

Buforowanie przygotowanych instrukcji

Wiele pul połączeń przechowuje w pamięci podręcznej przygotowane instrukcje w różnych zastosowaniach połączenia, co oznacza, że ​​jeśli wywołasz conn.prepareStatement("select ?") , zwróci ten sam PreparedStatement wystąpienie w kolejnych wywołaniach z tym samym ciągiem instrukcji. Jest to przydatne, aby uniknąć wielokrotnego przygotowywania tego samego ciągu na serwerze, gdy połączenia są zwracane do puli między transakcjami.

Opcja MySQL JDBC cachePrepStmts w ten sposób buforuje przygotowane oświadczenia (zarówno przygotowane przez klienta, jak i serwer) oraz buforuje „przygotowalność” oświadczenia. W MySQL jest kilka instrukcji, których nie można przygotować po stronie serwera. Sterownik spróbuje przygotować instrukcję na serwerze, jeśli uzna, że ​​jest to możliwe, a jeśli przygotowanie się nie powiedzie, powróci do instrukcji przygotowanej przez klienta. Ta kontrola jest kosztowna, ponieważ wymaga podróży w obie strony na serwer. Ta opcja spowoduje również buforowanie wyniku tego sprawdzenia.

Mam nadzieję, że to pomoże.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. mysql - WSTAW zakres dat do kolumn dat JEŚLI daty nie pokrywają się z istniejącymi

  2. Wybieranie losowych wierszy w MySQL

  3. Jak dodać w każdym tagu linku (a href) atrybut rel za pomocą php?

  4. Podstawowa musi zawierać wszystkie kolumny w błędzie lokalizacji partycjonowania tabeli?

  5. Dlaczego Railsy ignorują Rollback w (pseudo)zagnieżdżonej transakcji?