Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / методология больших запросов в Java / 25 сообщений из 39, страница 1 из 2
18.10.2013, 08:07:41
    #38432230
vlad_nal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
Здравствуйте !

Раньше разрабатывал в основном стендбайные приложения. Щас перешел на WEB.
И мучает вот какая проблема :
Вводные :
- есть таблица, например с 1 000 000 строк.
- есть веб приложение которое показывает эту таблицу в гриде
По ошибке пользователя, он задал слишком размазанные параметры, ну или не важно как, но запрос возвращает 1 мил строк.
На странице конечно, есть прейджинг, весь этот миллион не летит клиенту.

НО !
1. Вариант : если поступать как сделано сейчас, то : через Хибернейт открывается запрос, весь запрос перекачивается в коллекцию, после чего соединение с БД закрывается и работа идет с коллекцией.
В этом варианте получается. что апликейшен сервер является как бы хранилищем снапшотов для БД. Что на мой взгляд при таких обьемах весьма затратно!

2. Вариант: как делалось в стендбае (работали с Oracle поэтому буду его терминологию использовать): с ДБ возвращалась ссылка на курсор, из которой выкачивалось, ну например 500 записей, курсор не закрывался ! После чего записи показывались пользователю, и как только пользователь опускался скажем до 450-й записи, подкачивалось еще 500 записей и т.д.
Когда форма закрывалась - курсор освобождался.
Но это в стенд, что такой вариант с WEB не проканает, так как количество открытых коннектов к БД и курсоров быстро превысит все возможные пределы.
Или я не прав (интересует прежде всего Oracle, Postgres)?

Видится еще вариант 3 :
Делаем "окно" на сервере, то есть в запросе к БД указываем с какой по какую запись надо вернуть, мотаем курсор "в пустую" в БД до нужной записи, отдаем в Java , скажем 500 записей с нужной позиции, после чего закрываем соединение с БД.
Когда пользователь хочет 501-у запись, снова открываем соединение, кидаем в БД такой же запрос, мотаем до 501-й записи и отдаем с 501-й по 1001-у.
То есть в Java размер коллекции всегда 500 элементов, и не зависит от размера результирующего запроса.
Все вроде хорошо, одно смущает: данные могут изменяться в промежутках , и мы можем получить при 2-м (например) обращении те же самые записи(если скажем сортировка по дате ввода , и в промежутке между обращениями кто то успел ввести 500 новых записей). У пользователя может возникнуть ощущение что программа листает не корректно.

Подскажите , наверняка многие сталкивались с подобной проблемой : какие лучшие практики ?
Или есть ли какой то вариант 4 ?
Спасибо !
...
Рейтинг: 0 / 0
18.10.2013, 08:41:50
    #38432246
Niky4000
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
В своё время решали подобную проблему.
У нас используется как раз вариант 3.
Именно так и делается.
Проблему "некорректного пролистывания" решили так: order by date (которая является const'антой) и PrimaryKey. И всё. Никаких проблем.
...
Рейтинг: 0 / 0
18.10.2013, 09:16:03
    #38432280
oneHalf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
стендбайные приложения - это че за хрень? Знаю standby сервера, контроллеры домена и т.д., что переводится не иначе как резервные. Сдается мне, вы используете слово не понимая его смысл.
Все то о чем вы написали - классика, о которой можно прочесть набрав Paging, pagination.
А по пунктам:
1. Хибер представьте себе умеет делать пагинацию - это ваш вариант 3 с "окном".
2. вариант 2 - действительно только для "десктопов" с 2-х звенной архитектурой.

Ну а проблема ошибочного представления данных - нарушение целостности представления, которое может появиться из за того, что данные поменялись, сервер бд использовал другой план выполнения запроса и т.д. - это та весчь с которой "смирились" все, ну, по крайней мере, ожидают таких "глюков" и в состоянии объяснить их. Воспринимайте это как технологическое ограничение представления данных ).
...
Рейтинг: 0 / 0
18.10.2013, 09:57:21
    #38432344
cdtyjv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
Вы подняли очень интересную тему - как эффективно сделать pagination. Готовых решений, которые сходу вас устроят, тут нет. Но есть большой опыт, накопленный при решении этих проблем, который можно перенимать. Ищите по ключевому слову "pagination".
Дам вам несколько точек старта:
1) Можно не закрывать коннекшн, и по мере поступления запросов двигаться дальше в курсоре. Реализуется достаточно просто, но совершенно не масштабируется. На каждого юзера у вас будет одно долгоживущее соединение. Если у вас 10-20 юзер, и их не будет больше - то можете смело идти этим путем.
2) Можно на каждый запрос новой "страницы" делать новый запрос на весь датасет, и просто проматывать его. Начинает себя хуже вести по мере роста количества записей. Тут надо смотреть, как ведут себя юзеры. Если смотрят только первые несколько страниц - то ничего страшного не будет. Если же они идут глубоко по страницам - то проблемы будут нарастать со временем.
3) Можно, например, выдавать юзерам информацию с некоторым лагом. То есть, у вас есть, например, одна таблица с актуальными данными, которая меняется. А в другой таблице у вас read-only данные, которые перекачиваются из первой таблицы, например, раз в час. Этим данным выставляются какие-то дополнительные атрибуты (например, порядковый номер), по которым потом можно очень быстро искать. Это очень производительный вариант, отлично подходит для критичных по времени отклика приложений, но за это вы платите дополнительным гемором по разработке, и дополнительными требованиями к месту для хранения.
4) Можно сделать pagination с нефиксированным размером страницы и плавающими параметрами запроса. Например, вы ограничиваете размер ответа сервера в 25 записей. Первая страница выдает вам 25 записей, потом вы смотрите на "имя" или "дату обновления" последней из возвращенных записей, меняете запрос, и снова возвращаете следующие 25 записей. В зависимости от условий, он может вам вернуть, скажем 14 записей. Тогда вы их отображаете, а потом через AJAX делаете еще один запрос, который "добьет" WEB-форму до нужного размера.
5) Можно делать prefetch, возможно даже адаптивный префетч. То есть, у вас работает приложение, и вы собираете метрики пользователей. Потом по этим метрикам вы строите прогноз, насколько глубоко они обычно ходят. Наконец, основываясь на этом прогнозе, когда у вас юзер открывает первую страницу, вы в бэкгрануде, подгружаете, например, еще 4 страницы, и сохраняете в сессию, так как метрики вам сказали, что в среднем юзеры идут на 2-3 страницы вглубь.

И это далеко не все идеи. Как видите, подходов к решению этой проблемы очень много. И конкретный совет тут дать очень тяжело, так как выбор подхода зависит от множества факторов, которые известны только вам.
...
Рейтинг: 0 / 0
18.10.2013, 10:06:54
    #38432354
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
vlad_nalВсе вроде хорошо, одно смущает: данные могут изменяться в промежутках , и мы можем получить при 2-м (например) обращении те же самые записи(если скажем сортировка по дате ввода , и в промежутке между обращениями кто то успел ввести 500 новых записей). У пользователя может возникнуть ощущение что программа листает не корректно.

Подскажите , наверняка многие сталкивались с подобной проблемой : какие лучшие практики ?
Или есть ли какой то вариант 4 ?
Спасибо !
Для фиксации снапшота можно использовать либо:

Код: plsql
1.
2.
3.
alter session read only;
....
commit;


при этом для текущей сессии нельзя делать запись. Пока не придёт commit.

Или (начиная с 10 или 11 верссии) ретроспективные запросы:

Код: plsql
1.
2.
select dbms_flashback.get_system_change_number from dual;
select ...... as of scn <system_change_number>
...
Рейтинг: 0 / 0
18.10.2013, 10:12:21
    #38432362
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
oneHalfстендбайные приложения - это че за хрень?
Вероятно со standalone попутал.
...
Рейтинг: 0 / 0
18.10.2013, 10:25:40
    #38432390
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
vlad_nal1. Вариант : весь запрос перекачивается в коллекцию. Что на мой взгляд при таких обьемах весьма затратно!

Да, это просто не разумно для поиска. Коллекции можно полностью вычитывать в случае ассоциаций, и только делать такие ассоциации когда они не приводят к крупным выборкам. Задачи же inquiry полной загрузкой решать смысла нет.

vlad_nal2. Вариант: с ДБ возвращалась ссылка на курсор.
Но это в стенд, что такой вариант с WEB не проканает, так как количество открытых коннектов к БД и курсоров быстро превысит все возможные пределы.
Или я не прав (интересует прежде всего Oracle, Postgres)?
Прав лишь частично. Сколько у вас там юзеров-то? Сколько Oracle открытых курсоров переварит?

vlad_nalДелаем "окно" на сервере, то есть в запросе к БД указываем с какой по какую запись надо вернуть, мотаем курсор "в пустую" в БД до нужной записи,
Через Limit не?

vlad_nalТо есть в Java размер коллекции всегда 500 элементов, и не зависит от размера результирующего запроса.

Тут вообще какое дело. В итоге может оказаться что юзеру нафиг не надо более чем 50 первых записей. Остальные находятся уточнением запроса.

vlad_nalПодскажите , наверняка многие сталкивались с подобной проблемой : какие лучшие практики ?
Или есть ли какой то вариант 4 ?

Как уже написали выше - вариантов масса. Основная проблема в том что девелопер думает как это круто сделать скролл на миллион записей. А в итогде окажется что никто никогда из реальных юзеров дальше 2й страницы скролить не будет.
...
Рейтинг: 0 / 0
18.10.2013, 12:14:19
    #38432604
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
Лимит оффсет наше всё, а курсоры руками никто не мотает.
П.1 возможен. как скорее кэш, чем запрос, если кол-во записей ограничено.
...
Рейтинг: 0 / 0
18.10.2013, 12:15:47
    #38432610
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
Мне встречались 2-х звенки где миллион записей фетчились на толстого клиента.
Но там и клиент был особый. Какието графики. Аналитика. Кубы. Вобщем
имеют право. Специфика. Но на веб фетчить даже 500 - это глупо. Если для печати
на принтере - то надо сделать отдельную кнопоку. Типа там make Jasper
Report... save as и т.д. Но там нет pagination. Или нет такой проблемы.
...
Рейтинг: 0 / 0
18.10.2013, 12:18:55
    #38432619
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
Хехе, гугол пропатчили: "Извините, но Google не выдает более 1000 результатов".
Раньше заметно тормозил, если поставить offset=90000
...
Рейтинг: 0 / 0
18.10.2013, 12:20:20
    #38432624
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
ЛагманЛимит оффсет наше всё, а курсоры руками никто не мотает.
Hibernate мотает, когда в SQL диалекте нет пейджинга.
...
Рейтинг: 0 / 0
18.10.2013, 12:25:56
    #38432634
vlad_nal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
Ну естественно стендалон приложения имел ввиду, перепутал.

Да , про flash back query в Oracle я знаю.
Только они имеют ограниченное время жизни.

По всякому получается 3-й вариант, как наиболее универсальный.
Статистика статистикой, а защита от дурака в принципе должна присутствовать. Кто его (пользователя) знает, сегодня он дальше второй страницы не ходил, а тут его "прибило".

oneHalf
А как Хидер делает pagination ?
Я вот "мотаю" курсор на сервере БД (Oracle). А Хидбер будет "мотать" его на апликейшене ?
...
Рейтинг: 0 / 0
18.10.2013, 12:29:10
    #38432642
Penkov Vladimir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
хибер знает как работать с конкретной БД. для мускула подставит limit, для оракла сделает через rownum
...
Рейтинг: 0 / 0
18.10.2013, 12:31:51
    #38432651
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
vlad_nalКто его (пользователя) знает, сегодня он дальше второй страницы не ходил, а тут его "прибило".

Тю, так не давать юзерам больше 100 записей и баста.
Кстати, на счет Hibernate и paging-а. Если вдруг начнуться Join-ы. И хибенейт будет склеивать записи по ROOT ENTITY, то paging на уровне SQL не будет совпадать со страницами на уровне объектов.



vlad_nalА как Хидер делает pagination ?

"стендбай", "хидер". Вы делаете успехи.

vlad_nalЯ вот "мотаю" курсор на сервере БД (Oracle). А Хидбер будет "мотать" его на апликейшене ?
По-умолчанию paging реализован через LIMIT. Можно тот же paging сделать через перемотку курсора.
Есть и API для скрола
http://stackoverflow.com/questions/2826319/using-hibernates-scrollableresults-to-slowly-read-90-million-records
...
Рейтинг: 0 / 0
18.10.2013, 12:36:07
    #38432659
vlad_nal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
Ну, если все говорят про 3-й вариант, то в принципе никаких хитростей Хибера не нужно.
У меня приложение не предполагается крос-датабасе.
А на Oracle я умею "мотать" курсор ,так как архитектура приложения такова что я с select могу не работать, а перейти на PIPELINED функции. И "перемотка" на самом Oracle думаю будет значительно быстрее, чем это сделает Хибер, плюс меньше трафика между сервером БД и апликейшен.
...
Рейтинг: 0 / 0
18.10.2013, 12:39:09
    #38432664
Penkov Vladimir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
что то мне подсказывает что вы решаете проблемы, которых нет
...
Рейтинг: 0 / 0
18.10.2013, 12:42:26
    #38432669
vlad_nal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
Penkov Vladimir,

Ну как "нет", в принципе задумался о масштабируемости приложения.
Подумал может кто что "хитрое" предложит.
...
Рейтинг: 0 / 0
18.10.2013, 12:46:37
    #38432679
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
vlad_nalНу как "нет", в принципе задумался о масштабируемости приложения.
Подумал может кто что "хитрое" предложит.
За "хитростями" это к Oracle DBA. Со стороны Java никаких хитростей нет. Либо paging ну уровне SQL. Либо скролируемый курсор. Больше JDBC ничего не умеет.
...
Рейтинг: 0 / 0
18.10.2013, 12:55:48
    #38432705
vlad_nal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
Blazkowicz,

Да, наверно вы правы. Можно по шаманить со стороны Oracle.
Может shared mode и вариант 2 поможет, да только в Oracle курсоры только в перед скролируемые :-(
...
Рейтинг: 0 / 0
18.10.2013, 12:58:36
    #38432710
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
vlad_nalНу как "нет", в принципе задумался о масштабируемости приложения.
Подумал может кто что "хитрое" предложит.
При чем тут масштабируемость? Ни одному юзеру нафиг не нужен список длиннее сотни-другой элементов. Вот и не давайте ему больше. Всё будет ок с масштабируемостью тогда.
...
Рейтинг: 0 / 0
18.10.2013, 12:58:46
    #38432712
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
vlad_nalТолько они имеют ограниченное время жизни.

Какое время вы знаете?
...
Рейтинг: 0 / 0
18.10.2013, 12:59:44
    #38432717
vlad_nal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
mayton,

пока ролбак сегмент не почиститься
...
Рейтинг: 0 / 0
18.10.2013, 13:02:25
    #38432726
vlad_nal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
Blazkowicz,

ну то есть Вы предлагаете вариант 4 :
- ограничить выборку скажем 200 -300 -ми записями
- а если пользователь ввел критерии поиска, которые тянут на большее , то выводить ему сообщение : "Уточните запрос .... трам пам пам "
...
Рейтинг: 0 / 0
18.10.2013, 13:03:43
    #38432730
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
vlad_nalBlazkowicz,

Да, наверно вы правы. Можно по шаманить со стороны Oracle.
Может shared mode и вариант 2 поможет, да только в Oracle курсоры только в перед скролируемые :-(
Если вы взяли ретроспективный запрос то дёрните еще еще раз на предыдущую страницу.
Или если ресурсы позволяют (Хибер... фигли... ) и вы разбрасываетесь коллекциями
направо и налево - то спокойно храните предыдущую станицу. Это решит проблему
"нервного пользователя" который любит листать внезапно назад (!).

Кстати это сигнальчик к оптимизации работы Gui и пользователя вообще.
...
Рейтинг: 0 / 0
18.10.2013, 13:08:09
    #38432742
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
методология больших запросов в Java
vlad_nalmayton,

пока ролбак сегмент не почиститься
Ролбак умер. Его уже нету, брадт. Такова реальность.

Поищи по ключевым словам Flashback Query, ORA-01555, UNDO_RETENTION, retention guarantee

Да. И подружись с DBA. Это очень полезные связи. Я гарантирую это.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / методология больших запросов в Java / 25 сообщений из 39, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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