должен ли я активировать пул операторов c3p0?

мы запускаем стек java6/hibernate/c3p0/postgresql. Наш водитель JDBC 8.4-701.jdbc3

У меня есть несколько вопросов о подготовленных инструкций. Я читал отличный документ о Подготовленные Заявления

но у меня все еще есть вопрос, Как настроить c3p0 с postgresql.

на данный момент у нас

 c3p0.maxStatements = 0
 c3p0.maxStatementsPerConnection  =   0

в моем понимании подготовленные операторы и объединение операторов-это два разных вещи:

наш стек hibernate использует подготовленные операторы. PostgreSQL-это кэширование план исполнения. При следующем использовании того же оператора postgresql повторно использует план исполнения. Это экономит время планирования инструкций внутри БД.

кроме того, c3p0 может кэшировать экземпляры java " java.язык SQL.Объект PreparedStatement" это означает, что он кэширует объект java. Поэтому при использовании
c3p0.maxStatementsPerConnection = 100 он кэширует не более 100 различных
объекты. Это экономит время на создание объектов, но это не имеет ничего общего с база данных postgresql и ее подготовленные операторы.

верно?

поскольку мы используем около 100 различных операторов, я бы установил c3p0.maxStatementsPerConnection = 100

но документы c3p0 говорят в c3p0 известные недостатки

накладные расходы на объединение операторов слишком высокий. Для водителей, которые не проанализировать значительные предобработки PreparedStatements, объединение накладные расходы перевешивают любые сбережения. Заявление зачет, таким образом, выключен по умолчанию. Если ваш водитель делает preprocess PreparedStatements, особенно если он делает это через IPC с РСУБД, вы, вероятно, увидите значительное увеличение представления мимо включение объединения заявлений. (Сделать это путем установки свойства конфигурации maxStatements или maxStatementsPerConnection значение больше нуля.).

So: разумно ли активировать maxStatementsPerConnection с c3p0 и Postgresql? Есть ли реальная польза от его активации?

С уважением Яннинг!--2-->

2 ответов


Я не помню сразу, если Hibernate фактически хранит экземпляры PreparedStatement сам или полагается на поставщика подключения для их повторного использования. (Быстрое сканирование BatcherImpl предполагает, что он повторно использует последнее PreparedStatement при выполнении одного и того же SQL несколько раз подряд)

Я думаю, что точка зрения, которую пытается сделать документация c3p0, заключается в том, что для многих драйверов JDBC PreparedStatement не полезен: некоторые драйверы в конечном итоге просто сращивают параметры на стороне клиента и затем передайте встроенный оператор SQL в базу данных в любом случае. Для этих драйверов PreparedStatements не являются преимуществом вообще, и любые усилия по их повторному использованию тратятся впустую. (The PostgreSQL JDBC FAQ говорит, что это было в случае Postgresql до версии протокола sever 3, и есть более подробная информация в документация).

для драйверов, которые обрабатывают PreparedStatements с пользой, по-прежнему, вероятно, необходимо повторно использовать PreparedStatement случаях получить какую-либо выгоду. Например, если драйвер реализует:

  • подключение.prepareStatement (sql)-создание оператора на стороне сервера
  • PreparedStatement.выполнять.(.) etc-выполнить этот оператор на стороне сервера
  • PreparedStatement.close ()-освободить оператор на стороне сервера

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

вот почему c3p0 и другие пулы соединений также подготовили кэши операторов - это позволяет коду приложения избегать всего этого. Операторы обычно хранятся в некотором ограниченном пуле LRU, поэтому общие операторы повторно используют экземпляр PreparedStatement.

последние фрагменты головоломки, что Драйверы JDBC могут сами решить быть умными и сделать это; и серверы могут также решить быть умными и обнаружить клиента, отправляющего заявление, которое структурно похоже на предыдущее.

учитывая, что Hibernate сам не хранит кэш экземпляров PreparedStatement, вам нужно, чтобы c3p0 сделал это, чтобы получить от них выгоду. (Которые должны быть уменьшены накладные расходы для общих операторов из-за повторного использования кэшированных планов). Если c3p0 не кэширует подготовленные операторы, затем драйвер просто увидит, как приложение готовит инструкцию, выполняет ее, а затем снова закрывает. Похоже, что драйвер JDBC имеет "порог" параметр для избежания накладных расходов на подготовку/выполнение сервера в случае, когда приложение всегда делает это. Итак, да, вам нужно иметь кэширование операторов c3p0 do.

надеюсь, что это поможет, извините, это немного запыхалось. Ответ да.


помните, что операторы должны быть кэшированы на подключение что будет означать, что вам придется потреблять довольно большой кусок памяти, и пройдет много времени, прежде чем вы увидите какую-либо выгоду. Поэтому, если вы установите его на использование 100 операторов для кэширования, это на самом деле 100*количество подключений или 100/нет подключений, но вам все равно потребуется некоторое время, пока ваш кэш не будет иметь никакого значимого эффекта.