Как справиться с разбиением на страницы для большого, не материализуемого набора результатов в Oracle и Java - PullRequest
0 голосов
/ 10 ноября 2011

Я имею дело с какой-то проблемой здесь.Веб-приложение, созданное на основе java, вызывает хранимую процедуру в oracle, которая имеет в качестве параметров out varchars и параметр, тип которого является курсором ref, возвращающим тип записи (оба явно определены).Содержимое указателя ref собирается с помощью сложного запроса, который, как я предполагаю, запускает O (n) в зависимости от количества записей в таблице.

Идея состоит в том, чтобы разбить результат на сервере, так как вседанные вызывают большую задержку (500 записей занимают около 40-50 секунд из-за расчета и разрешения соединения).Я уже перестроил запрос, используя row_number ()

open out_rcvar for
  SELECT *
    FROM ( select a, b, c,..., row_number() over (order by f, g) rn
            from t1, t2,...
            where some_conditions
    ) where rn between initial_row and final_row
    order by rn;

, чтобы избежать подхода с ограничением по смещению (и его эквивалентности в oracle).Но вот в чем проблема, пользователь хочет меню нумерации страниц, как

[first ||<< 5предыдущий ||1 2 3 4 5 ||следующая5 >> ||last]

и знание количества строк подразумевает подсчет (следовательно, «запрос») всего пакета и получение целых 50 сек.Какой подход я мог бы использовать здесь?

Заранее благодарен за вашу помощь.

РЕДАКТИРОВАТЬ: длинный запрос не должен быть установлен как материализованное представление, потому что данные в записях должны быть обновлены какон запрашивается (веб-приложение выполняет некоторые операции с данными и ему необходимо знать, является ли выбранный элемент «доступным» или «проданным»)

Ответы [ 3 ]

0 голосов
/ 10 ноября 2011

Возможно, вы могли бы подумать о создании временной таблицы. Вы можете хранить свои результаты тут же, а затем использовать какой-то механизм подкачки. Таким образом, вычисление будет выполнено один раз. Тогда вы только выберете данные, которые будут довольно быстрыми.

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

0 голосов
/ 10 ноября 2011

Вы можете сделать что-то вроде:

 SELECT *
    FROM ( select  count(*),a, b, c,..., row_number() over (order by f, g) rn
            from t1, t2,...
            where some_conditions
    ) where rn between initial_row and final_row
    order by rn;

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

0 голосов
/ 10 ноября 2011

Какова производительность, если вы выбираете не столбцы, а просто счетчик для определения строк?Это приемлемо?

И используйте это как руководство для построения нумерации страниц.

В противном случае у нас нет возможности без знания счетчика построить число страниц как (1,2,3,45)

Другой вариант - не отображать количество страниц, нопросто покажи следующий и предыдущий.

Только мои мысли.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...