powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / постраничный вывод(именно постраничный)
7 сообщений из 7, страница 1 из 1
постраничный вывод(именно постраничный)
    #37729260
Андрей Васильевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!
Решил сделать постраничный вывод в DB2. Дело дошло до sql запроса. Самый простой способ это где-то(например, как у меня переменная сессии в вэб-приложении) хранить стек со значениями первичного ключа(ПК суррогатный, инкрементный), а запрос типа:
Код: sql
1.
select ID_T,NAME_T from TABL where ID_T>=x order by ID fetch first n only


где, x-значение первичного ключа из стека(где первое значение 0)
n-кол-во записей на странице.
Все замечательно, НО в данном случае можно перемещаться назад и вперед на 1 шаг. Согласен, можно при перемещениях вперед сохранять историю о страницах и указывать их на странице. Можно определить общее количество строк и понять сколько будет страниц. Но вот как найти значения ID для каждой новой порции не выбирая всех данных? То есть хочется выполнив поиск, на странице получить перечень номеров страниц, нажимая на которые произвольным образом получить соответствующую порцию данных. Понятно, что если в указанном выше запросе max будет работать для всей выборки, а не n первых записей. Поделитесь мыслью.
...
Рейтинг: 0 / 0
постраничный вывод(именно постраничный)
    #37729369
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Андрей Васильевич,

Добрый день.
Пока вы не получите все строки, вы не сможете в точности определить, сколько вам строк вернётся.
Не выполняя запрос, вы можете получить от оптимизатора только примерное количество строк, которое вернётся.
В 9.7.3 появился метод для получения такой информации.
Код: java
1.
2.
3.
java.sql.PreparedStatement pst = ...;
...
int rcnt = ((com.ibm.db2.jcc.DB2PreparedStatement) pst).getEstimateRowCount();
...
Рейтинг: 0 / 0
постраничный вывод(именно постраничный)
    #37729409
Андрей Васильевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну вот почему нельзя так сделать?
Код: sql
1.
select max(ID_T) from TABL where ID_T>=x order by ID fetch first n only
...
Рейтинг: 0 / 0
постраничный вывод(именно постраничный)
    #37729440
Андрей Васильевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хотя даже если бы и работало это, то количество запросов было бы равное количеству страниц(это в первом запросе при определении количества страниц).
...
Рейтинг: 0 / 0
постраничный вывод(именно постраничный)
    #37729753
CawaSPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Васильевич,

Пока не материализована выборка, сказать, что там будет на N-й cтранице невозможно, если не хранить это прекалькулированным. Т.е. надо выбрать весь set, который мы собираемся представлять пользователю.

Но если это много, то:
- Страница 3487 результата - это не то, что вообще обрабатываемо человеком через GUI, т.е. можно ограничиться где-нибудь 50-ю страницами при сотне результатов на странице, т.е. 5 000 записей (а может и меньше). Это скорее всего в пределах одного extent'а, т.е. с диска читается за раз.
- С сортировкой внимательно смотреть, чтобы реальной сортировки не происходило а был только index scan.

Эти 5 000 ID'шников (или пограничные значения для страниц) хранить в кэше, а для следующих (если всё-таки есть желание сохранить возможность добраться до них через UI) уже повторять запрос, по мере необходимости включая дополнительные результаты.

Ну, можно ещё MQT cоорудить:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create table TABL_PAGES (ID) as (
 with t(r_id, id_t) as (
   select ROW_NUMBER() OVER(order by ID_T), ID_T from TABL
 )
 select ROW_NUMBER() OVER(order by MIN(ID_T)) as PAGE_NUM, MIN(ID_T) as ID_T from t group by r_id/20
) DATA INITIALLY DEFERRED REFRESH DEFERRED;

-- some index creations
...

-- По необходимости дёргать 
refresh table TABL_PAGES;



PS Ещё момент, FETCH FIRST N ROWS ONLY игнорируется оптимизатором, а только подсказывает оптимальные размеры буферов для клиента (ну и физически ограничивает выборку), добавляйте ещё OPIMIZE FOR N ROWS, хотя в данном случае может не иметь значения.
И обратите внимание на получаемые планы, для "where ID_T>=x ...", если x параметризован, то оно может превратиться в FULLSCAN по таблице.
...
Рейтинг: 0 / 0
постраничный вывод(именно постраничный)
    #37730069
CawaSPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ВасильевичНу вот почему нельзя так сделать?
Код: sql
1.
select max(ID_T) from TABL where ID_T>=x order by ID fetch first n only



BTW Почти можно (с поправкой на то, что "rows" в "n rows only" пропущено), но
- fetch first ... применяется к финальному result set'у (т.е. честно отдаст одну единственную строчку);
- order by и список колонок в result-set'е не согласуется.

Можно вот так cформулировать:
Код: sql
1.
2.
3.
4.
with t1(ID_T) as (
 select ID_T from TABL where ID_T>=x order by ID_T fetch first n rows only
)
select max(ID_T) from t1


Но да, чтобы добраться до N-й страницы, нужно N запросов сделать.
...
Рейтинг: 0 / 0
постраничный вывод(именно постраничный)
    #37741495
Андрей Васильевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Точно. Запрос не полный. Должен быть:
Код: sql
1.
select ID_T,NAME_T from TABL where ID_T>=x order by ID fetch first n rows only
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / постраничный вывод(именно постраничный)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]