Mysql
 sql >> база данни >  >> RDS >> Mysql

Каква е разликата между cachePrepStmts и useServerPrepStmts в MySQL JDBC драйвер

Първо, важно е да се прави разлика между клиентски и сървърни подготвени оператори.

Подготвени от клиента изявления

Подготвените от клиента изявления са "емулирани" подготвени изявления. Това означава, че низът на SQL инструкция е токенизиран от страна на клиента и всички заместители се заменят с литерални стойности, преди да се изпрати изразът на сървъра за изпълнение. Пълен SQL оператор се изпраща на сървъра при всяко изпълнение. Можете да използвате общия дневник, за да проучите как работи това. напр.

следния код:

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

ще се покаже в дневника:

255 Query  select 42
255 Query  select 43

"Заявката" показва, че на ниво протокол COM_QUERY командата се изпраща със следния низ на оператора.

Подготвени от сървъра изявления

Подготвените от сървъра оператори са "истински" подготвени оператори, което означава, че текстът на заявката се изпраща на сървъра, анализира се и информацията за място и резултатът се връща на клиента. Това получавате, когато задавате useServerPrepStmts=true . Низът на оператора се изпраща на сървъра само веднъж с COM_STMT_PREPARE обадете се (документирано тук ). Всяко изпълнение се извършва чрез изпращане на COM_STMT_EXECUTE с подготвения манипулатор на оператора и литералните стойности, които да заменят заместващите.

За контраст с примера, подготвен от клиента, можем да използваме подобен блок код (но този път с активирани изрази, подготвени от сървъра):

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

И дневникът ще покаже:

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

Можете да видите, че изявлението е подготвено преди да бъде изпълнено. Регистраторът ни прави услуга и показва пълния оператор за изпълнението, но всъщност само стойностите за място се изпращат от клиент на сървър за всяко изпълнение.

Кеширане на подготвени изявления

Много пулове за връзки ще кешират подготвени оператори при използване на връзка, което означава, че ако извикате conn.prepareStatement("select ?") , той ще върне същия PreparedStatement екземпляр при последователни извиквания със същия низ от оператори. Това е полезно, за да се избегне подготвянето на един и същ низ на сървъра многократно, когато връзките се връщат към пула между транзакциите.

Опцията MySQL JDBC cachePrepStmts ще кешира подготвените оператори по този начин (както клиентски, така и сървърни подготвени оператори), както и ще кешира "подготвимостта" на изявление. Има някои изявления в MySQL, които не могат да се подготвят от страна на сървъра. Драйверът ще се опита да подготви изявление на сървъра, ако смята, че е възможно и, ако подготовката не успее, ще се върне към подготвен от клиента оператор. Тази проверка е скъпа поради изискване за двупосочно пътуване до сървъра. Опцията също ще кешира резултата от тази проверка.

Надявам се това да помогне.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PHP mysql за изпълнение на задача след 30 секунди

  2. InnoDB отнема повече от час за импортиране на 600MB файл, MyISAM за няколко минути

  3. Възможно ли е да се преброят две колони в една и съща заявка

  4. Автоматично връщане назад, ако COMMIT TRANSACTION не бъде достигната

  5. Как да изчислим съотношението с помощта на sql заявка?