Кэшировать PreparedStatement для каждого соединения или позволить пулу соединений обрабатывать его?

Какая стратегия кеширования быстрее и на сколько?

1) Пул PreparedStatement (по пулу соединений). Приложение не кеширует.

for (int i=0; i<1000; i++) {
    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    preparedStatement.setObject(1, someValue);
    preparedStatement.executeQuery();
    preparedStatement.close();
}

2) Кеширование на уровне приложения. Нет пула PreparedStatement.

PreparedStatement preparedStatement = connection.prepareStatement(sql);
for (int i=0; i<1000; i++) {
    preparedStatement.clearParameters();
    preparedStatement.setObject(1, someValue);
    preparedStatement.executeQuery();
}
preparedStatement.close();

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

http://drupal.org/node/550124#comment-2224630, похоже, указывает это кэширование на уровне приложения более эффективно, чем пул PreparedStatement, но разница незначительна. Я хотел бы увидеть больше тестов, прежде чем принимать решение.


person Gili    schedule 19.01.2011    source источник
comment
Этот своего рода микротест редко дает какие-либо полезные данные. Реальное использование будет сильно различаться в зависимости от модели использования, базовой реализации базы данных, сети, памяти на сервере базы данных и других вещей. Почему бы вам просто не написать свой код, чтобы он работал, с тестами. Затем, если он окажется слишком медленным, вы можете обновить реализацию и убедиться, что программное обеспечение продолжит работать.   -  person time4tea    schedule 19.01.2011
comment
Я пытаюсь понять, стоит ли вводить в фреймворк кеширование на уровне приложений. Это повлияет на базу пользователей в целом, поэтому оптимизация для конкретного варианта использования не поможет. Есть ли какой-нибудь уважаемый тест базы данных, который мы могли бы изменить вместо этого?   -  person Gili    schedule 19.01.2011
comment
Ну, а кто-нибудь из пользователей запрашивал эту функцию? Если нет, то, возможно, это никому не нужно, и вы могли бы сэкономить некоторые усилия, вместо того, чтобы внедрять новую функцию, которая может не делать много ... просто подумайте!   -  person time4tea    schedule 19.01.2011


Ответы (1)


Кэширование на уровне приложения было бы более эффективным, особенно если вы выполняете пакетное выполнение.

Даже при использовании пула соединений объем сетевых накладных расходов, необходимых для подготовки соединения (ответный и четвертый подтверждения) и его закрытия каждый раз, делает его не только медленнее, но и увеличивает затраты на уровне ЦП как на SQL-сервере, так и на клиентском сервере.

person trilogy    schedule 09.10.2018
comment
(Насколько я понимаю) пул соединений работает не так. Пул соединений происходит на стороне клиента. Когда клиент закрывает соединение, оно фактически остается открытым, и последующий клиент может повторно использовать его и любые ресурсы, которые часто воссоздаются (например, PreparedStatements). - person Gili; 10.10.2018
comment
Процесс создания соединения происходит как на клиенте, так и на сервере. Пул создает несколько подключений и, следовательно, несколько подключений к серверу. Вы можете видеть это во время мониторинга на сервере (количество подключений в пуле). Соединение закрывается после выполнения запроса, и другое соединение добавляется в пул в режиме реального времени. - person trilogy; 10.10.2018
comment
PreparedStatement - это не то же самое, что пул соединений. Я думаю, вы перепутали пакетирование с объединением. Для объединения вам понадобится сторонняя библиотека, например HikariCP (github.com/brettwooldridge/HikariCP) или BoneCP. - person trilogy; 10.10.2018