|
|
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
Известно, что для экранного представления (в т.ч. и для JTable) нет смысла выдавать пользователю чрезмерно большие выборки. В принципе, именно этим я до сих пор и руководствовался, т.е. предпочитал заставить пользователя яснее сформулировать сввой запрос, а не выдавать ему по первому требованию миллионы записей чтобы он мог просмотреть сотню. :) Однако, в последнее время я столкнулся с необходимостью работы с "тонкими" клиентами. Не буду вдаваться в подробности, но для них уже 500 - 1000 записей явлется чрезмерно большой выборкой + очень часто отсутствует возможность полноценного кэширования на клиенте. Причем, сам запрос бывает сложным и выполняется значительное время. На стороне СУБД решаются часть проблем, но на клиенте остается вопрос: Для ускорения выборки, на клиенте используется небольшой буфер в RAM + выборка записей по частям. Но сам буфер редко может вместить в себя всю выборку. Соответственно, надо JTable сообщить число рядов, которое позволило бы ей запросить доп. порцию информации из моей модели данных, а не макс. емкость буфера. Причем очень нежелательно ограничивать это число рядов, рассчитывая его как размер буфера + размер очередной выборки (почему, см. ниже про непоследовательное перемещение по набору данных). Крайне нежелательно вызывать нечто вроде select count(*) ... ввиду того, что выборка сложна и не стоит удваивать кол-во времени на ожидание точного подсчета числа записей, которое само по себе никому не нужно. Подсчет статистики (и обращение к таблицам оной для оценки числа рядов, это я про ORACLE) тоже не выход, хотя бы потому, что сложной выборке из нескольких таблиц такая статистика как рыбе зонтик. Вернуть "заведомо большее число рядов" тоже не получается, ввиду того, что объем выборки может значительно колебаться даже в течении дня и одна и та же выборка может вернтуь и 10 записей и все 500. Если листать таблицу строго постранично, то нет проблем, но часто по нескольким первым страницам пользователь производит определенную оценку и хочет сместиться куда-то ближе к концу выборки и не листать по десять строк все 500 записей. Еще раз подчеркну, что для "толстого" клиента было близко к маразму на "тонком" вполне адекватное требование. Человек может и хочет просмотреть все 500 записей и он не понимает зачем ему надо еще уточнять запрос - он ведь пользуется всеми его результатами. А "уточнить вопрос" за него я не могу, т.к. не знаю объем выборки, т.е. у пользователя есть возможность задать четкие критерии, но нет никакого желания их еще более уточнять - он и так получил строго то, что ему нужно, а у меня нет понятия, что конкретно ему нужно, я только могу тупо попытаться ему выдать что-то, что находится на N рядов ниже/выше той страницы, которую он просматривает. Соотв. переопределение getRowCount(), когда есть проблемы даже с приближенной оценкой объема выборки, не спасает. Вот и вопрос - можно ли что-то с этим сделать, или, увы, если пользователь позволил себе запросить не очередную последовательную порцию данных, то тупо считать count(*) и пытаться скорректировать реальное число записей? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2005, 16:40:38 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
многа букав не четал жу-жу вопрос в том как узнать сколько строчек вернул запрос? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2005, 16:49:33 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
Если да, то вот ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2005, 16:57:31 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
Вопрос в том, что базу данных обмануть не получится - для того, чтобы получить число записей их, эти записи надо выбрать. Это долго и часто можно обойтись без этого, т.к. пользователю редко есть дело до конкретного числа строк при больших выборках. Соответственно, если мы пролистываем записи (неважно в начало или конец) последовательно, то и нет необходимости в таком подсчете. Если же вдруг нам взбрело в голову переместиться, скажем сразу на сотню-другую записей, скажем, в конец выборки то мы, не зная реального числа столбцов, рискуем оказаться в положении, когда не просто нечего будет выбирать, а еще придется "отвечать за базар" перед пользователем - т.е. в ответ на такой запрос нельзя его просто послать, как это делает, скажем Google, а придется в ответ реально найти, где же данные кончаются и выдать ему их. Прошу прощения за длинный вопрос и пояснения, просто ситуация IMHO не совсем обычная. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2005, 17:50:59 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
авторЕсли же вдруг нам взбрело в голову переместиться, скажем сразу на сотню-другую записей, скажем, в конец выборки то мы, не зная реального числа столбцов, рискуем оказаться в положении, когда не просто нечего будет выбирать, а еще придется "отвечать за базар" перед пользователем - т.е. в ответ на такой запрос нельзя его просто послать, как это делает, скажем Google, а придется в ответ реально найти, где же данные кончаются и выдать ему их. А почему нельзя сделать как гугл? Я конеффно может не въезжаю в тему тонких клиентов но думал что фенька здесь в том что всяческие нагружающие расчёты происходят на стороне сервера, а клиенту выдаётся только то что его слабый желудок может переваритть. Почему количество строк нельзя выяснить на сервере и исходя из этого не вычислить размер/количество страниц выдаваемых клиенту? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2005, 18:00:23 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
Сделать как в Гугл можно (и нужно) на "толстом" клиенте. Посмотрите на его идеологию- Гугл нам сообщает, что есть где-то, скажем, 10000 страниц (как он оценивает это число на его совести) при этом он совершенно справедливо отправит меня к такой-то матери, если я ему скажу- прекрасно, вот и выдай-ка мне 9970 страницу. :) С "тонким" клиентом на такую реакцию я никак не рассчитываю, это все равно как тот же Гугл выдал бы мне, что всего найдено десять страниц, но запросто мог бы меня послать, если я попрошу все навсего десятую, но сразу после первой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2005, 18:08:41 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
то есть мой браузер это толстый клиент? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2005, 18:25:26 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
Нет, так себя ведет Google. :) Теперь представьте себе, что за Google себя выдает "тонкий" клиент, который смело заявляет, что может выдать 10 страниц, но при запросе этой самой десятой ведет себя, с точки зрения нормального пользователя, странно - вдруг заявляет, что он пошутил и у него нет 10 страниц. Мало того, он теперь заявляет, что у него всего 9 страниц, вы говорите, чтобы он выдал вам, в таком случае, девятую, а он попять "пошутил" и заявил, что и девяти у него нет (ну, или если повезет с потолочной оценкой реального кол-ва записей, то 9 таки выдал). Что мы могли понять и простить Google c его нежеланием выдать 10000 страницу, никак не получится простить клиенту - ведь 10 страниц с точки зрения пользователя вполне ничтожное число. Разумеется, этот тонкий клиент мог бы не заноситься, а сразу точно подсчитать сколько страниц он реально может выдать (тогда не то что с 10-ой, но и с 500 страницей особых проблем не было бы), но первые результаты поиска пришлось бы ждать не 2 секунды, а десять - что не есть хорошо. Вообще же предлагаю аналогию с Google все же не развивать. Попробую кратко сформулировать, что проблема возникает из двух причин: 1) Нежелания считать точное кол-во записей перед выдачей результата. 2) Невозможности буферизации всего на клиенте и желания разбить выборку на ряд выборок меньшего размера с целью ускорения получения первых результатов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2005, 18:38:37 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
Интуитивно мне почему-то кажется, что использовать так как гугль здесь не пойдет. Не тот масштаб. Так что если надо выбрать 10000 записей и посчитать их, то надо выбрать и посчитать. А дальше уже кешировать на сервере и т. д. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2005, 18:40:26 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
А можно конкретно описать что же за система у вас ? автор"тонкий" клиент, который смело заявляет, что может выдать 10 страниц, но при запросе этой самой десятой ведет себя, с точки зрения нормального пользователя, странно - вдруг заявляет, что он пошутил и у него нет 10 страниц. Я просто не могу понять с какой радости тонкий клиент будет что-то выдавать тем более в таких количествах и кому? Он же вроде должен только получать инфорамцию. Какой-то тонкий сервер получается. Или подразумевается что вся инфа сразу сливается с сервера на клиент, а уж он должен изворачиваться как её отобразить? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2005, 18:46:19 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
"Интуитивно мне почему-то кажется, что использовать так как гугль здесь не пойдет. Не тот масштаб. Так что если надо выбрать 10000 записей и посчитать их, то надо выбрать и посчитать. А дальше уже кешировать на сервере и т. д." Увы мне, Ивану Васильевичу, вот и мне так кажется, а очень не хочется. :( Конечно, обмануть программу не получится, вопрос в другом - а нельзя ли как-нибудь "обмануть" пользователя - т.е. что-то скорее из теории GUI. Вот ведь тот же Google обманывает, а большинство ведь даже не знает про это. :) Все, пошел домой, может по дороге чего придумаю. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2005, 18:47:23 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
Я просто не могу понять с какой радости тонкий клиент будет что-то выдавать тем более в таких количествах и кому? Он же вроде должен только получать инфорамцию. Какой-то тонкий сервер получается. Выдавать он будет пользователю на экран. :) Кол-во вовсе не будет являться "таким" - "такми" оно, увы, является только для "железа" тонкого клиента, ну еще и для медленной сети. Для человека же это кол-во как раз является весьма разумным и он будет крайне разочарован, обнаружив, что "железо" с ним не согласно. :( Я описал проблему подробно в первом сообщении, понимаю, что такие монстрики читать никому не охота, но, честное слово, я не нарочно, ну не получается объяснить короче. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2005, 18:51:40 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
carper "Интуитивно мне почему-то кажется, что использовать так как гугль здесь не пойдет. Не тот масштаб. Так что если надо выбрать 10000 записей и посчитать их, то надо выбрать и посчитать. А дальше уже кешировать на сервере и т. д." Увы мне, Ивану Васильевичу, вот и мне так кажется, а очень не хочется. :( Конечно, обмануть программу не получится, вопрос в другом - а нельзя ли как-нибудь "обмануть" пользователя - т.е. что-то скорее из теории GUI. Вот ведь тот же Google обманывает, а большинство ведь даже не знает про это. :) Все, пошел домой, может по дороге чего придумаю. :) В TOAD интересно сделано. Когда смотришь содержимое таблички, то показывается скроллБар и пронумерованные строчки с данными. Чем больше откручиваешь вниз, тем большие номера начинают отображаться и тем меньше становится бегунок скроллБара :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2005, 19:10:35 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
А почему нельзя посчитать количество строк выборки заранее. Обычно строки в выборку добавляются и удаляются в строго определенных местах. Организоваться спец. служебную таблицу, где будет храниться количество строк различных выборок. Эта таблица будет меняться когда пользователь добавляется или удаляет строки и эта процедура почти не будет занимать времени. При выводе отчета мы уже будем заранее знать, сколько в нем строк. Правда если перед постронием отчета задается куча условий и фльтров, то работать это не будет или же будет огромное количество записей в служебных таблицах, за которыми надо будет следить, хотя тут тоже можно подумать как эту служ. таблицу организовать. Плюс здесь надо подумать как обрабатывать ситуации когда пользователь сформировал отчет, потом ему надо перейти в конец отчета, например, а количество строк уже изменилось. Думаю это тоже решаемо. Криво конечно :) Или я опять неправильно понял вопрос? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.06.2005, 07:53:02 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
NotGonnaGetUs В TOAD интересно сделано. Когда смотришь содержимое таблички, то показывается скроллБар и пронумерованные строчки с данными. Чем больше откручиваешь вниз, тем большие номера начинают отображаться и тем меньше становится бегунок скроллБара :) TOAD вроде как использует буферизацию запроса на клиенте в файл. Изменение поведения скроллбара в зависимости от кол-ва записей вопрос интересный, но пока мне хватает "тупого" поведения - т.е. поведения по-умолчанию. (У O'Reily есть описание элегантного способа того, как сделать скроллбар более "чуствительным и полезным" на больших выборках - там getRowCount всегда возвращает весьма небольшое число, а перемещение по записям идет за счет использования механизма индексации страниц - мне это способ не кажется очень надежным, т.к. можно легко где-то сделать ошибку и забыть прирастить индекс, плюс из getValueAt желательно убрать все, чт отолько можно - иначе получим слишком медленную отрисовку таблиц). GMaxА почему нельзя посчитать количество строк выборки заранее. Просто потому, что точные критерии выборки нельзя знать заранее, поэтому вариант с созданием snapshots (или аналогов) или даже просто постоянных таблиц + подсчет записей не подходит. Обычно строки в выборку добавляются и удаляются в строго определенных местах. Эту фразу не понял, в выборку ничего не добавляется и не удаляется, query и есть query, а записи в таблицы, на которых он построен, уж никак не добавляются или не удаляются в каких-то загадочных определенных местах. Плюс здесь надо подумать как обрабатывать ситуации когда пользователь сформировал отчет, потом ему надо перейти в конец отчета, например, а количество строк уже изменилось. Думаю это тоже решаемо. Криво конечно :) Ну, это как раз не проблема, пользователь, который запрашивает выборку, не умещающуюся в одноразовый запрос, из изменяющихся таблиц, должен быть готов к слегка непредсказуемым результатам, например, к тому что изменилось и кол-во строк и их содержимое (или поставить пиво DBA и попросить его разрешить клиенту держать транзакцию на уровне сеанса, а не отдельного селекта) . :) Поэтому у меня скорее стояла задача выборки заранее неопределенного объема из ОТНОСИТЕЛЬНО постоянных таблиц, т.е. противоречий в чтении, в пределах одной транзакции, точнее сеанса, не будет, причем это обеспечивается отнюдь не построением временной таблицы для каждого запроса (есть более эффективные частные способы). Вся беда в том, что несмотря на постоянное для данного сеанса содержимое таблиц оценить конечный объем выборки нельзя, ну не могу я на каждый чих, например, на изменение диапазона дат, заранее подсчитать, что получится. Боюсь все же, что без count мне не обойтись. :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.06.2005, 09:33:35 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
carper Обычно строки в выборку добавляются и удаляются в строго определенных местах. Эту фразу не понял, в выборку ничего не добавляется и не удаляется, query и есть query, а записи в таблицы, на которых он построен, уж никак не добавляются или не удаляются в каких-то загадочных определенных местах.Строки в таблицы, на основании которых делаются выборки добавляются в нескольких заранее известных процедурах. Это имелось ввиду. carperВся беда в том, что несмотря на постоянное для данного сеанса содержимое таблиц оценить конечный объем выборки нельзя, ну не могу я на каждый чих, например, на изменение диапазона дат, заранее подсчитать, что получится.Если пользователь формирует отчет по реализации за 10 лет с детализацией по документам и номенклатуре товара, то он должен быть готов к тому, что отчет может строиться не 5 минут а намного больше. Можно отслеживать большие временные интервалы и предупреждать об этом пользователя перед началом формирования отчета. carperБоюсь все же, что без count мне не обойтись. :(Боюсь, что да. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.06.2005, 09:48:46 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
А может, результаты запроса прямо на сервере заливать во временную таблицу, одновременно подсчитывая количество строк. А на клиента потом выбирать нужные строки из этой временной таблицы. А? А когда клиент закрывает отчёт, грохать эту таблицу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2005, 17:38:12 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
FuzzyА может, результаты запроса прямо на сервере заливать во временную таблицу, одновременно подсчитывая количество строк. А на клиента потом выбирать нужные строки из этой временной таблицы. А? А когда клиент закрывает отчёт, грохать эту таблицу . M$-овец? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2005, 18:51:01 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
я что-то сильно глупое предложил, да? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2005, 20:09:19 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
1. Денормализация и индексы не выручают? авторпотому, что точные критерии выборки нельзя знать заранее поэтому вариант с созданием snapshots (или аналогов) ... не подходит 2. Почему не подходит? Можете привести пример? Обычно в отчете небольшое количество имерений, например дата, клиент, товар и сумма. Можно хранить агрегированную по этим измерениям табличку. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2005, 06:54:42 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
FuzzyА может, результаты запроса прямо на сервере заливать во временную таблицу, одновременно подсчитывая количество строк. А на клиента потом выбирать нужные строки из этой временной таблицы. А? А когда клиент закрывает отчёт, грохать эту таблицу. Можно, только с сотней тонких клиентов и с невозможность оценить объем выборки заранее (+ работа одновременно и с толстыми клиентами, для которых совсем другой критерий нормальной величины выборки) делают тогда уж предпочтительней вариант с count(). Liner Обычно в отчете небольшое количество имерений, например дата, клиент, товар и сумма. Можно хранить агрегированную по этим измерениям табличку. У меня несколько другая задача, часто тонкими клиентами являются бизнес-аналитики, рекламщики и прочая братия, они отличаются частым формированием сложных и разнородных запросов по самым не предсказуемым критериям. Тут вообще дело в другом, когда человек работает с достаточно большим кол-ом записей его редко интересует их точное число, более того, очень редко он действительно просматривает все записи. Соответственно, мне кажется разумным не считать их вообще (ведь count потребует выборки их всех, разумеется, индексы тут очень существенно помогут и это отнюдь не смертельный вариант), а просто как-то попробовать создать у пользователя иллюзию, наподобие Google. Только сильно подозреваю, что я занимаюсь фигней, и чем дальше, тем больше, пока решил просто дать человеку возможность или постраничного перемещения, или перехода строго на конец набора, с соответствующей задержкой. :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2005, 12:34:18 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
carperУ меня несколько другая задача, часто тонкими клиентами являются бизнес-аналитики, рекламщики и прочая братия, они отличаются частым формированием сложных и разнородных запросов по самым не предсказуемым критериям. Ну не уникальные же у них каждый раз запросы, они же не в TOAD, например, запросы пишут? Естественно есть какой-то интерфейс где они задают типы выборок, параметры и т.д. По этим параметрам и нужно агрегировать. ИМХО Если учесть и еще к тому же частые запросы, то можно подумать над созданием специального хранилища данных, пусть оно будет денормализовано, пусть будет избыточность, в дополнение к основным - какие-нить агрегативные таблички но запросы будут отрабатывать на ура. carperТут вообще дело в другом, когда человек работает с достаточно большим кол-ом записей его редко интересует их точное число, более того, очень редко он действительно просматривает все записи. Может сделать параметр - максимальное количество возвращаемых записей, пусть человек сам решает, нужна ли ему вся информация или только несколько первых записей. И тогда будет логично что всю выборку надо долго ждать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2005, 13:56:47 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
в догонку, может поможет если оракл у вас, то можно оптимизировать средствами СУБД тут могу наврать в теории только видел, не бейте сильно но вроде там есть возможность разделять таблицы на партиции по каким-то определенным критериям (например данные за 5 лет разделили по году), логически у тебя будет одна таблица - физически несколько, если параметры запроса например попадают в заданные критерии - анализ в пределах 1 года данных, будет обрабатывать только одну выделенную табличку, там есть еще матриализованные представления и т.д. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2005, 14:06:32 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
NotGonnaGetUs В TOAD интересно сделано. Когда смотришь содержимое таблички, то показывается скроллБар и пронумерованные строчки с данными. Чем больше откручиваешь вниз, тем большие номера начинают отображаться и тем меньше становится бегунок скроллБара :) А ты попробуй на табличке в несколько миллионов записей за бегунок хватануться и вниз мотнуть его, совсем неинтересно будет :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2005, 14:09:45 |
|
||
|
JTable и большие выборки
|
|||
|---|---|---|---|
|
#18+
чем тоньше клиент, тем толще сервер ;-) Может вам хранимку написать на сервере в которой в качестве параметра передается запрос, она его выполняет, результат записывает во временную таблицу и возвращает имя временной таблицы и количество 'affected' записей? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2005, 14:19:53 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=33386916&tid=2145053]: |
0ms |
get settings: |
19ms |
get forum list: |
32ms |
check forum access: |
8ms |
check topic access: |
8ms |
track hit: |
79ms |
get topic data: |
25ms |
get forum data: |
6ms |
get page messages: |
129ms |
get tp. blocked users: |
3ms |
| others: | 351ms |
| total: | 660ms |

| 0 / 0 |
