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

мы выполняем стопку java6/hibernate/c3p0/postgresql. Наш Драйвер JDBC 8.4-701.jdbc3

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

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

В данный момент мы имеем

 c3p0.maxStatements = 0
 c3p0.maxStatementsPerConnection  =   0

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

Наш быть в спящем режиме стек использует подготовленные операторы. Postgresql кэширует план выполнения. В следующий раз тот же оператор используется, postgresql снова использует план выполнения. Это экономит время, планируя операторы в DB.

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

Правильно?

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

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

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

Так: действительно ли разумно активировать maxStatementsPerConnection c3p0 и Postgresql? Существует ли реальная выгода, активирующая его?

наилучшие пожелания Janning

18
задан Janning 27 May 2010 в 11:43
поделиться

2 ответа

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

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

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

  • Соединение.prepareStatement (sql) - создать оператор на стороне сервера
  • PreparedStatement.execute (..) и т.д. - выполнить этот оператор на стороне сервера
  • PreparedStatement.close () - освободить оператор на стороне сервера

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

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

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

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

Надеюсь, это поможет, извините, это немного затянуто. Ответ - да .

25
ответ дан 30 November 2019 в 08:21
поделиться

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

2
ответ дан 30 November 2019 в 08:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: