Вопрос

Я выполняю запрос к таблице в базе данных postgresql.База данных находится на удаленной машине.В таблице около 30 подтаблиц с использованием postgresql. возможность разделения.

Запрос вернет большой набор результатов, около 1,8 миллиона строк.

В моем коде я использую поддержку Spring JDBC, метод JdbcTemplate.query, но мой Обработчик обратного вызова строки не вызывается.

Я предполагаю, что драйвер jdbc postgresql (я использую версию 8.3-603.jdbc4) накапливает результат в памяти перед вызовом моего кода.Я думал, конфигурация fetchSize мог бы это контролировать, но я попробовал и ничего не изменилось.Я сделал это как руководство по PostgreSQL рекомендуется.

Этот запрос работал нормально, когда я использовал Oracle XE.Но я пытаюсь перейти на postgresql из-за функции секционирования, которая недоступна в Oracle XE.

Моё окружение:

  • Постгреск 8.3
  • Windows Server 2008 Корпоративная 64-разрядная версия
  • JRE 1.6 64-битная
  • Весна 2.5.6
  • Драйвер Postgresql JDBC 8.3-603
Это было полезно?

Решение

Чтобы использовать курсор для получения данных, вам необходимо установить тип ResultSet ResultSet.TYPE_FORWARD_ONLY (по умолчанию) и автоматически зафиксировать значение false в дополнение к настройке размера выборки.На это есть ссылка в документе, на который вы ссылаетесь, но вы прямо не упомянули, что выполнили эти шаги.

Будьте осторожны со схемой секционирования PostgreSQL.Он действительно творит ужасные вещи с оптимизатором и может вызвать серьезные проблемы с производительностью там, где их быть не должно (в зависимости от особенностей ваших данных).В любом случае, ваша строка состоит всего из 1,8 млн строк?Нет причин, по которым его нужно было бы секционировать только на основе размера, учитывая, что он соответствующим образом проиндексирован.

Другие советы

Могу поспорить, что ни один клиент вашего приложения не нуждается в 1,8 млн строк одновременно.Вам следует подумать о разумном способе разбить результаты на более мелкие части и дать пользователям возможность перебирать их.

Это то, что делает Google.Когда вы выполняете поиск, могут быть миллионы совпадений, но они возвращают 25 страниц за раз, предполагая, что вы найдете то, что хотите, на первой странице.

Если это не клиент и результаты каким-то образом обрабатываются, я бы рекомендовал позволить базе данных обработать все эти строки и просто вернуть результат.Нет смысла возвращать 1,8 млн строк только для того, чтобы выполнить расчет на среднем уровне.

Если ни один из них не применим, у вас настоящая проблема.Время переосмыслить это.

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

Я бы порекомендовал переориентироваться — начать думать об этом как о решении для отчетности.

Свойство fetchSize работало, как описано в руководство по постгресу.

Моя ошибка заключалась в том, что я установил auto commit = false для соединения из пула соединений, который не использовался подготовленным оператором.

Спасибо всем за отзывы.

Я сделал все вышеперечисленное, но мне нужен был еще один кусочек:убедитесь, что вызов заключен в транзакцию, и установите транзакцию только для чтения, чтобы состояние отката не требовалось.

Я добавил это: @Transactional(readOnly = true)

Ваше здоровье.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top