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

трябва ли да активирам обединяването на изрази c3p0?

Не си спомням случайно дали Hibernate всъщност съхранява екземпляри на PreparedStatement или разчита на доставчика на връзка, за да ги използва повторно. (Бързо сканиране на BatcherImpl предполага, че той използва повторно последния PreparedStatement, ако изпълнява същия SQL няколко пъти подред)

Мисля, че целта, която документацията на c3p0 се опитва да направи, е, че за много JDBC драйвери PreparedStatement не е полезен:някои драйвери в крайна сметка просто ще свържат параметрите от страна на клиента и след това ще предадат изградения SQL израз към базата данни така или иначе . За тези драйвери PreparedStatements изобщо не са предимство и всяко усилие за повторното им използване е напразно. (Често задаваните въпроси за Postgresql JDBC казват, че това е било така за Postgresql преди версия 3 на протокола на сървъра и има по-подробна информация в документацията).

За драйвери, които обработват PreparedStatements полезно, все още е вероятно да е необходимо действително да използвате повторно екземпляри на PreparedStatement, за да извлечете полза. Например, ако драйверът прилага:

  • Connection.prepareStatement(sql) - създайте изявление от страна на сървъра
  • PreparedStatement.execute(..) etc - изпълнете този израз от страна на сървъра
  • PreparedStatement.close() - освобождава изявлението от страна на сървъра

Като се има предвид това, ако приложението винаги отваря подготвен израз, изпълнява го веднъж и след това го затваря отново, все още няма полза; всъщност може да е по-лошо, тъй като сега има потенциално повече двупосочни пътувания. Така че приложението трябва да се задържи на екземпляри на PreparedStatement. Разбира се, това води до друг проблем:ако приложението виси на твърде много и всеки израз от страна на сървъра консумира някои ресурси, тогава това може да доведе до проблеми от страна на сървъра. В случай, че някой използва директно JDBC, това може да се управлява от красиви изявления, за които е известно, че могат да се използват повторно и следователно са подготвени; някои не са и просто използват преходни инстанции вместо това. (Това е прескачане на другото предимство на подготвените оператори:обработка на екраниране на аргументи)

Ето защо c3p0 и други пулове за връзки също имат подготвени кешове на изрази - това позволява на кода на приложението да избягва работа с всичко това. Изявленията обикновено се съхраняват в някакъв ограничен LRU пул, така че често срещаните оператори използват повторно екземпляр на PreparedStatement.

Последните части от пъзела са, че JDBC драйверите могат сами да решат да бъдат умни и да направят това; и сървърите могат сами да решат да бъдат умни и да открият клиент, който изпраща изявление, което е структурно подобно на предишно.

Като се има предвид, че Hibernate сам по себе си не пази кеш на екземпляри на PreparedStatement, трябва да накарате c3p0 да направи това, за да се възползвате от тях. (Което трябва да бъде намалено режийните разходи за общи изявления поради повторно използване на кеширани планове). Ако c3p0 не кешира подготвени оператори, тогава драйверът просто ще види как приложението подготвя оператор, изпълнява го и след това го затваря отново. Изглежда, че JDBC драйверът има настройка за "праг" за избягване на излишните разходи на сървъра за подготовка/изпълнение в случай, когато приложението винаги прави това. Така че, да, трябва да имате c3p0 do кеширане на изрази.

Надявам се това да помогне, съжалявам, че е малко дълго. Отговорът еда .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Надграждане на PostgreSQL 11 до PostgreSQL 13 с TimescaleDB и PostGIS в Linux с помощта на pg_upgrade

  2. Как работи LocalTimeStamp() в PostgreSQL

  3. Буфери (кръг) в PostGIS

  4. Прословутото java.sql.SQLException:Не е намерен подходящ драйвер

  5. Съхраняване на дълги двоични (сурови) низове