Поддерживает ли Oracle прокручиваемые курсоры на стороне сервера через JDBC?

StackOverflow https://stackoverflow.com/questions/1060545

  •  21-08-2019
  •  | 
  •  

Вопрос

В настоящее время, работая над внедрением ERP-системы на базе OFBiz, мы столкнулись со следующей проблемой:часть кода фреймворка вызывает ResultSet.last(), чтобы узнать общее количество строк результирующего набора.Используя драйверы Oracle JDBC версий 11 и 10, он пытается кэшировать все строки в клиентской памяти, приводя к сбою JVM, поскольку в ней недостаточно места в куче.

После исследования проблема, по-видимому, заключается в том, что Oracle JDBC реализует курсор с возможностью прокрутки на стороне клиента, а не на сервере, с использованием кэша.Используя драйвер datadirect, эта проблема решена, но кажется, что вызов resultset.last() занимает слишком много времени для завершения, поэтому сервер приложений прерывает транзакцию

есть ли какой-нибудь способ реализовать прокручиваемые курсоры через jdbc в oracle, не прибегая к драйверу datadirect?

и какой самый быстрый способ узнать длину данного результирующего набора??

Заранее спасибо Исмаэль

Это было полезно?

Решение

"какой самый быстрый способ узнать длину данного результирующего набора" ЕДИНСТВЕННЫЙ способ действительно узнать это - посчитать их все.Вы хотите знать, сколько СМИТОВ в телефонной книге.Ты их пересчитываешь.Если это небольшой набор результатов, к которому пришли быстро, это не проблема.НАПРИМЕР, в телефонной книге будет не так уж много Гэндальфов, и вы, вероятно, все равно захотите заполучить их всех.

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

Чтобы избежать кэширования всего результирующего набора на клиенте, вы можете попробовать

select id, count(1) over () n from junk;

Тогда каждая строка будет иметь дополнительный столбец (в данном случае n) с количеством строк в результирующем наборе.Но для подсчета по-прежнему потребуется столько же времени, так что по-прежнему велика вероятность тайм-аута.

Компромисс заключается в том, чтобы получить первые сто (или тысячу) строк и не беспокоиться о разбивке на страницы после этого.

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

предложенный вами "обходной путь" с count в основном удваивает работу, выполняемую сервером БД.Он должен сначала просмотреть все, чтобы подсчитать количество результатов, а затем сделать то же самое + вернуть результаты.Гораздо лучше метод, упомянутый Гэри (count(*) over() - аналитика).Но даже здесь весь результирующий набор должен быть создан до того, как первый вывод будет возвращен клиенту.Таким образом, это потенциально замедляет потребление памяти для больших выходных данных.

Лучший способ, на мой взгляд, - это выбрать на экране только ту страницу, которую вы хотите (+ 1, чтобы определить, что следующая существует), напримерстроки с 21 по 41.И есть еще одна кнопка (usecase), чтобы подсчитать их все на тот (редкий) случай, если кому-то это понадобится.

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