|
|
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
Здравствуйте ! Раньше разрабатывал в основном стендбайные приложения. Щас перешел на 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 ? Спасибо ! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 08:07:41 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
В своё время решали подобную проблему. У нас используется как раз вариант 3. Именно так и делается. Проблему "некорректного пролистывания" решили так: order by date (которая является const'антой) и PrimaryKey. И всё. Никаких проблем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 08:41:50 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
стендбайные приложения - это че за хрень? Знаю standby сервера, контроллеры домена и т.д., что переводится не иначе как резервные. Сдается мне, вы используете слово не понимая его смысл. Все то о чем вы написали - классика, о которой можно прочесть набрав Paging, pagination. А по пунктам: 1. Хибер представьте себе умеет делать пагинацию - это ваш вариант 3 с "окном". 2. вариант 2 - действительно только для "десктопов" с 2-х звенной архитектурой. Ну а проблема ошибочного представления данных - нарушение целостности представления, которое может появиться из за того, что данные поменялись, сервер бд использовал другой план выполнения запроса и т.д. - это та весчь с которой "смирились" все, ну, по крайней мере, ожидают таких "глюков" и в состоянии объяснить их. Воспринимайте это как технологическое ограничение представления данных ). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 09:16:03 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
Вы подняли очень интересную тему - как эффективно сделать pagination. Готовых решений, которые сходу вас устроят, тут нет. Но есть большой опыт, накопленный при решении этих проблем, который можно перенимать. Ищите по ключевому слову "pagination". Дам вам несколько точек старта: 1) Можно не закрывать коннекшн, и по мере поступления запросов двигаться дальше в курсоре. Реализуется достаточно просто, но совершенно не масштабируется. На каждого юзера у вас будет одно долгоживущее соединение. Если у вас 10-20 юзер, и их не будет больше - то можете смело идти этим путем. 2) Можно на каждый запрос новой "страницы" делать новый запрос на весь датасет, и просто проматывать его. Начинает себя хуже вести по мере роста количества записей. Тут надо смотреть, как ведут себя юзеры. Если смотрят только первые несколько страниц - то ничего страшного не будет. Если же они идут глубоко по страницам - то проблемы будут нарастать со временем. 3) Можно, например, выдавать юзерам информацию с некоторым лагом. То есть, у вас есть, например, одна таблица с актуальными данными, которая меняется. А в другой таблице у вас read-only данные, которые перекачиваются из первой таблицы, например, раз в час. Этим данным выставляются какие-то дополнительные атрибуты (например, порядковый номер), по которым потом можно очень быстро искать. Это очень производительный вариант, отлично подходит для критичных по времени отклика приложений, но за это вы платите дополнительным гемором по разработке, и дополнительными требованиями к месту для хранения. 4) Можно сделать pagination с нефиксированным размером страницы и плавающими параметрами запроса. Например, вы ограничиваете размер ответа сервера в 25 записей. Первая страница выдает вам 25 записей, потом вы смотрите на "имя" или "дату обновления" последней из возвращенных записей, меняете запрос, и снова возвращаете следующие 25 записей. В зависимости от условий, он может вам вернуть, скажем 14 записей. Тогда вы их отображаете, а потом через AJAX делаете еще один запрос, который "добьет" WEB-форму до нужного размера. 5) Можно делать prefetch, возможно даже адаптивный префетч. То есть, у вас работает приложение, и вы собираете метрики пользователей. Потом по этим метрикам вы строите прогноз, насколько глубоко они обычно ходят. Наконец, основываясь на этом прогнозе, когда у вас юзер открывает первую страницу, вы в бэкгрануде, подгружаете, например, еще 4 страницы, и сохраняете в сессию, так как метрики вам сказали, что в среднем юзеры идут на 2-3 страницы вглубь. И это далеко не все идеи. Как видите, подходов к решению этой проблемы очень много. И конкретный совет тут дать очень тяжело, так как выбор подхода зависит от множества факторов, которые известны только вам. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 09:57:21 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
vlad_nalВсе вроде хорошо, одно смущает: данные могут изменяться в промежутках , и мы можем получить при 2-м (например) обращении те же самые записи(если скажем сортировка по дате ввода , и в промежутке между обращениями кто то успел ввести 500 новых записей). У пользователя может возникнуть ощущение что программа листает не корректно. Подскажите , наверняка многие сталкивались с подобной проблемой : какие лучшие практики ? Или есть ли какой то вариант 4 ? Спасибо ! Для фиксации снапшота можно использовать либо: Код: plsql 1. 2. 3. при этом для текущей сессии нельзя делать запись. Пока не придёт commit. Или (начиная с 10 или 11 верссии) ретроспективные запросы: Код: plsql 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 10:06:54 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
oneHalfстендбайные приложения - это че за хрень? Вероятно со standalone попутал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 10:12:21 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
vlad_nal1. Вариант : весь запрос перекачивается в коллекцию. Что на мой взгляд при таких обьемах весьма затратно! Да, это просто не разумно для поиска. Коллекции можно полностью вычитывать в случае ассоциаций, и только делать такие ассоциации когда они не приводят к крупным выборкам. Задачи же inquiry полной загрузкой решать смысла нет. vlad_nal2. Вариант: с ДБ возвращалась ссылка на курсор. Но это в стенд, что такой вариант с WEB не проканает, так как количество открытых коннектов к БД и курсоров быстро превысит все возможные пределы. Или я не прав (интересует прежде всего Oracle, Postgres)? Прав лишь частично. Сколько у вас там юзеров-то? Сколько Oracle открытых курсоров переварит? vlad_nalДелаем "окно" на сервере, то есть в запросе к БД указываем с какой по какую запись надо вернуть, мотаем курсор "в пустую" в БД до нужной записи, Через Limit не? vlad_nalТо есть в Java размер коллекции всегда 500 элементов, и не зависит от размера результирующего запроса. Тут вообще какое дело. В итоге может оказаться что юзеру нафиг не надо более чем 50 первых записей. Остальные находятся уточнением запроса. vlad_nalПодскажите , наверняка многие сталкивались с подобной проблемой : какие лучшие практики ? Или есть ли какой то вариант 4 ? Как уже написали выше - вариантов масса. Основная проблема в том что девелопер думает как это круто сделать скролл на миллион записей. А в итогде окажется что никто никогда из реальных юзеров дальше 2й страницы скролить не будет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 10:25:40 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
Лимит оффсет наше всё, а курсоры руками никто не мотает. П.1 возможен. как скорее кэш, чем запрос, если кол-во записей ограничено. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 12:14:19 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
Мне встречались 2-х звенки где миллион записей фетчились на толстого клиента. Но там и клиент был особый. Какието графики. Аналитика. Кубы. Вобщем имеют право. Специфика. Но на веб фетчить даже 500 - это глупо. Если для печати на принтере - то надо сделать отдельную кнопоку. Типа там make Jasper Report... save as и т.д. Но там нет pagination. Или нет такой проблемы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 12:15:47 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
Хехе, гугол пропатчили: "Извините, но Google не выдает более 1000 результатов". Раньше заметно тормозил, если поставить offset=90000 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 12:18:55 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
ЛагманЛимит оффсет наше всё, а курсоры руками никто не мотает. Hibernate мотает, когда в SQL диалекте нет пейджинга. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 12:20:20 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
Ну естественно стендалон приложения имел ввиду, перепутал. Да , про flash back query в Oracle я знаю. Только они имеют ограниченное время жизни. По всякому получается 3-й вариант, как наиболее универсальный. Статистика статистикой, а защита от дурака в принципе должна присутствовать. Кто его (пользователя) знает, сегодня он дальше второй страницы не ходил, а тут его "прибило". oneHalf А как Хидер делает pagination ? Я вот "мотаю" курсор на сервере БД (Oracle). А Хидбер будет "мотать" его на апликейшене ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 12:25:56 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
хибер знает как работать с конкретной БД. для мускула подставит limit, для оракла сделает через rownum ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 12:29:10 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
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 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 12:31:51 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
Ну, если все говорят про 3-й вариант, то в принципе никаких хитростей Хибера не нужно. У меня приложение не предполагается крос-датабасе. А на Oracle я умею "мотать" курсор ,так как архитектура приложения такова что я с select могу не работать, а перейти на PIPELINED функции. И "перемотка" на самом Oracle думаю будет значительно быстрее, чем это сделает Хибер, плюс меньше трафика между сервером БД и апликейшен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 12:36:07 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
что то мне подсказывает что вы решаете проблемы, которых нет ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 12:39:09 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
Penkov Vladimir, Ну как "нет", в принципе задумался о масштабируемости приложения. Подумал может кто что "хитрое" предложит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 12:42:26 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
vlad_nalНу как "нет", в принципе задумался о масштабируемости приложения. Подумал может кто что "хитрое" предложит. За "хитростями" это к Oracle DBA. Со стороны Java никаких хитростей нет. Либо paging ну уровне SQL. Либо скролируемый курсор. Больше JDBC ничего не умеет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 12:46:37 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, Да, наверно вы правы. Можно по шаманить со стороны Oracle. Может shared mode и вариант 2 поможет, да только в Oracle курсоры только в перед скролируемые :-( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 12:55:48 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
vlad_nalНу как "нет", в принципе задумался о масштабируемости приложения. Подумал может кто что "хитрое" предложит. При чем тут масштабируемость? Ни одному юзеру нафиг не нужен список длиннее сотни-другой элементов. Вот и не давайте ему больше. Всё будет ок с масштабируемостью тогда. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 12:58:36 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
vlad_nalТолько они имеют ограниченное время жизни. Какое время вы знаете? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 12:58:46 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
mayton, пока ролбак сегмент не почиститься ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 12:59:44 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, ну то есть Вы предлагаете вариант 4 : - ограничить выборку скажем 200 -300 -ми записями - а если пользователь ввел критерии поиска, которые тянут на большее , то выводить ему сообщение : "Уточните запрос .... трам пам пам " ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 13:02:25 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
vlad_nalBlazkowicz, Да, наверно вы правы. Можно по шаманить со стороны Oracle. Может shared mode и вариант 2 поможет, да только в Oracle курсоры только в перед скролируемые :-( Если вы взяли ретроспективный запрос то дёрните еще еще раз на предыдущую страницу. Или если ресурсы позволяют (Хибер... фигли... ) и вы разбрасываетесь коллекциями направо и налево - то спокойно храните предыдущую станицу. Это решит проблему "нервного пользователя" который любит листать внезапно назад (!). Кстати это сигнальчик к оптимизации работы Gui и пользователя вообще. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 13:03:43 |
|
||
|
методология больших запросов в Java
|
|||
|---|---|---|---|
|
#18+
vlad_nalmayton, пока ролбак сегмент не почиститься Ролбак умер. Его уже нету, брадт. Такова реальность. Поищи по ключевым словам Flashback Query, ORA-01555, UNDO_RETENTION, retention guarantee Да. И подружись с DBA. Это очень полезные связи. Я гарантирую это. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2013, 13:08:09 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38432705&tid=2128382]: |
0ms |
get settings: |
9ms |
get forum list: |
18ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
37ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
87ms |
get tp. blocked users: |
2ms |
| others: | 196ms |
| total: | 370ms |

| 0 / 0 |
