ОРИГИНАЛЬНАЯ ПОПЫТКА (вероятно, неправильно, см. Изменения ниже): Я не эксперт по курсорам, но я почти уверен, что использование курсора не означает, что оператор SELECT вернется сразу , Сервер все еще должен выполнить его, как любой другой запрос, что может занять время. Я рекомендую попытаться выяснить, какая часть системы блокируется.
После того, как Java-программа "зависает", запустите SELECT * FROM pg_stat_activity
, используя отдельный клиент базы данных (например, psql). Если вы видите свой запрос в списке, это означает, что сервер все еще обрабатывает его.
Вы также можете изменить log_min_duration_statement
сервера PostgreSQL на (в качестве примера) 1000. Затем, после перезапуска PostgreSQL (или используя pg_ctl reload
или что-то в этом роде), снова запустите программу. Как только запрос завершится, вы должны увидеть строку в файле журнала PostgreSQL, указывающую, сколько времени это заняло.
Удачи!
РЕДАКТИРОВАТЬ: Я нашел эту запись в блоге , которая описывает аналогичные проблемы.
[Запросу] потребовалось несколько секунд, чтобы вернуться, и поэтому возникла отрицательная
начальный опыт для пользователя. С тех пор я узнал, что
Мне нужно было просто применить некоторые настройки среды.
Вот они:
set enable_sort = off
set enable_seqscan = off
Вы можете посмотреть их. Они просто мешают PostgreSQL пытаться
выполнить сортировку файлов, объединение файлов или последовательное сканирование, если есть какой-либо индекс
подарок. Теперь, за пределами курсора, вы все равно получите значительный
задержка, потому что все строки будут доставлены независимо. Там должно быть
клиентская методология для пейджинга, иначе сервер не будет
способен доставлять данные кусками. Capice
Но внутри курсора вышеприведенное работает довольно хорошо. Почти
мгновенно.
У меня нет таблиц с 100 миллионами строк, поэтому я не могу это проверить. Но вы можете попробовать.
РЕДАКТИРОВАТЬ 2: Раздел 11.4 руководства PostgreSQL объясняет, почему enable_sort
особенно важно:
Важным частным случаем является ORDER BY в сочетании с LIMIT n: an
явная сортировка должна будет обработать все данные, чтобы идентифицировать первый
n строк, но если существует индекс, соответствующий ORDER BY, первый n
строки могут быть получены напрямую, без сканирования остатка.