Имеется тупоголовый упрямый заказчик, который настойчиво хочет, чтобы по запросу пользователя с нечетко сформированным условием выдавались все затребованные строки, даже если их окжатся миллион или более... Результаты должны отображаться в DataGrid, при этом не волочь всю выборку на клиента сразу и через сеть, а сперва получить и отобразить первую небольшую порцию даннх в надежде на то, что у юзера хватит ума не листать список до миллионой записи, а сформулировать запрос конкретнее. Однако если у юзера возникнет желание полистать выборку или перейти к последней записи, у него должна быть такая возможность. И еще — если клиент захочет перескочить на конец, ему необходимо подгрузить только хвостик выборки, не занимая сеть передачей всего массива строк... В общем, прицел к возможности работы в таком стиле по медленному каналу.
Да, и еще клиенское приложение должно уметь позволять редактировать данные из этой выборки.
Сервер БД — MS SQL,в котором Server-side курсоры, как известно, реализованы в зародыше, пользоваться которым в реальной жизни можно только в варианте forward only и без знания заранее числа строк в выборке.
Заказчик согласен на организацию при доступе к таким данным paging, т.е. данные из большой выборки возвращаются кусочками фиксированного размера с возмножностью навигации между ними вперед/назад начало/конец.
Я нашел решение, удовлетворяющее сим противоречивым и варварским требованиям — читать данные порциями через DataReader на сервере приложений, напихивая порции в DataSet'ы (при этом снимая с его строк каким-то образом признак того, что они добавлены ручками — но это уже делали, хотя тоже неприятные), сохраняя уже прочитанные DataSet и выдавая эти самые DataSet'ы клиенту по запросу. Но это так некрасиво, к тому же пока не будет достигнут конец выборки, придется для этого запроса держать лишнее соединение с БД. Так ведь и пул исчерпать недолго...
В общем, я прошу народ поделиться, кто и как решал такую проблему. А то чувство преследует, что изобретаю велосипед с квадратными колесами.
Благодарю заранее всех, кто откликнется.
Re: Работа с большими выборками в Windows-приложениях .NET
Здравствуйте, Archistratig, Вы писали:
A>Доброе время суток всем!
A>Имеется тупоголовый упрямый заказчик,
Это не заказчик тупоголовый, а .NET недоделанный!!! А вообще можно пользоваться старым ADO через ComInterop.
A>В общем, я прошу народ поделиться, кто и как решал такую проблему. А то чувство преследует, что изобретаю велосипед с квадратными колесами.
В этом смысле пока .NET на квадратных колесах стоит... А нам-то ехать нужно!
Re[2]: Работа с большими выборками в Windows-приложениях .NE
Здравствуйте, Anton Burtsev, Вы писали:
A>>Имеется тупоголовый упрямый заказчик, AB>Это не заказчик тупоголовый, а .NET недоделанный!!! А вообще можно пользоваться старым ADO через ComInterop.
A>>В общем, я прошу народ поделиться, кто и как решал такую проблему. А то чувство преследует, что изобретаю велосипед с квадратными колесами. AB>В этом смысле пока .NET на квадратных колесах стоит... А нам-то ехать нужно!
Таки да.. Но ведь и ADO тоже не решает эту проблему, поскольку сервер-сайдовые курсоры MS SQL и есть те самые квадратные колеса. В этот отношении .NET — это небольшой поворот лицом к людям в этой застарелой M$ проблеме. Но поворот такой маленький, что видана все та же ж..., только в анфас
Похоже, снова придется извращаться. Грустно...
Re[2]: Работа с большими выборками в Windows-приложениях .NE
Здравствуйте, Anton Burtsev, Вы писали:
A>>Имеется тупоголовый упрямый заказчик, AB>Это не заказчик тупоголовый, а .NET недоделанный!!! А вообще можно пользоваться старым ADO через ComInterop.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Anton Burtsev, Вы писали:
A>>>Имеется тупоголовый упрямый заказчик, AB>>Это не заказчик тупоголовый, а .NET недоделанный!!! А вообще можно пользоваться старым ADO через ComInterop.
AVK>А кто доделанный?
JDBC+ORACLE, например (из того, что пробовал). Естественно касательно данной проблемы. У всех свои недостатки.
ЗЫ: Недоделанный — не значит плохой (а-ля недобитый, недоносок, недо...) А значит недоделанный. Я думаю, что они таки вернут/сделают серверные курсоры. А то памяти на них не напасёшься, всё из базы выгребать...
Re[4]: Работа с большими выборками в Windows-приложениях .NE
Здравствуйте, Anton Burtsev, Вы писали:
AVK>>А кто доделанный? AB>JDBC+ORACLE, например (из того, что пробовал). Естественно касательно данной проблемы. У всех свои недостатки.
Ну и как там подобную проблему решить? Если MSSQL еще COUNT() довольно быстро считает, то у ORACLE все может быть весьма печально. А без количества записей в выборке описанную задачку решить нельзя.
AB>ЗЫ: Недоделанный — не значит плохой (а-ля недобитый, недоносок, недо...) А значит недоделанный. Я думаю, что они таки вернут/сделают серверные курсоры.
Серверные курсоры не панацея от всех бед. Память будет жраться, не на клиенте, так на сервере. В данном конкретном случае действительно неверный подход.
Здравствуйте, AndrewVK, Вы писали:
AVK>Ну и как там подобную проблему решить? Если MSSQL еще COUNT() довольно быстро считает, то у ORACLE все может быть весьма печально. А без количества записей в выборке описанную задачку решить нельзя.
AVK>Серверные курсоры не панацея от всех бед. Память будет жраться, не на клиенте, так на сервере. В данном конкретном случае действительно неверный подход.
В данном конкретном случае память будет действительно жраться, и пусть лучше она будет она жраться на сервере приложений, чем на сервере БД — тут я с M$ в общем-то солидарен...Другое дело, что если уж данные закэшировались на сервере приложений, они вполне могли бы предоставить виндовым клиентам нечто вроде сервер-сайдового курсора для уже закэшированной выборки. Для ASP-то они так подложились — но не все же заказчики мечтают работать через боузер...?
А так они побуждают тащить результат выборки между слоями на клиента целиком, что совсем в такой ситуации не нужно.
Кстати, от COUNT() толку при решении этой задачи мало. Тем более, что заранее посчитанный COUNT() может окзаться неактуальным, если кто-то успеет в промежутке межу SELECT COUNT() и SELECT выборки выполнить INSERT/DELETE. Не блокировать же таблицы на то время, пока последняя строка выборки не вылезет из DataReader ? Тут нужен RecordCount, и для него иметь возможнсть знать, достигнут уже конец выборки или еще нет, т.е. что он нам сейчас показывает...
Кстити, никто не пытался делать под подобную задачу кастомный DataSet, и что из этого получалось, если кто пробовал?
Спасибо.
Re[6]: Работа с большими выборками в Windows-приложениях .NE
Здравствуйте, Archistratig, Вы писали:
A>В данном конкретном случае память будет действительно жраться, и пусть лучше она будет она жраться на сервере приложений, чем на сервере БД — тут я с M$ в общем-то солидарен...Другое дело, что если уж данные закэшировались на сервере приложений, они вполне могли бы предоставить виндовым клиентам нечто вроде сервер-сайдового курсора для уже закэшированной выборки.
Уж больно это специфичная логика. Все равно в реальности ты будешь писать что то свое.
A>Кстати, от COUNT() толку при решении этой задачи мало. Тем более, что заранее посчитанный COUNT() может окзаться неактуальным, если кто-то успеет в промежутке межу SELECT COUNT() и SELECT выборки выполнить INSERT/DELETE.
Ну значит будет ошибка. Если она неприемлема, то в приведенной постановке задача разумными методами нерешаема.
Здравствуйте, Archistratig, Вы писали:
A>Кстати, от COUNT() толку при решении этой задачи мало. Тем более, что заранее посчитанный COUNT() может окзаться неактуальным, если кто-то успеет в промежутке межу SELECT COUNT() и SELECT выборки выполнить INSERT/DELETE. Не блокировать же таблицы на то время, пока последняя строка выборки не вылезет из DataReader ? Тут нужен RecordCount, и для него иметь возможнсть знать, достигнут уже конец выборки или еще нет, т.е. что он нам сейчас показывает...
A>Кстити, никто не пытался делать под подобную задачу кастомный DataSet, и что из этого получалось, если кто пробовал?
A>Спасибо.
Недели 2 назад подобный вопрос я поднимал на многих форумах.
Он для меня и сейчас является актуальным.
А решение я выбралд такое:
датасет работает в двух режимах:
— кэшируемый (все полученные записи кэшируются)
— оконный (кэшируется только определенное "окно" записей, но здесь возникают проблемы с представлением отдной таблицы разными вьюхами, ее я пока еще не решил).
Написал все свои объкты, внутрь которых положил соответсвующие объекту ADO.NET. Свойстов Count у таблиц и вьюх вытаскиваются отдельным запросом с сервера. На клиент изначально предедаются только схема БД.
Данные закачиваются пока по требованию, но планирую делать упреждающую закачку данных. + к этому реализована еще некоторая специфичная функцианальность из-за которой и началось все это дело.
Если у Вас есть еще какие-либо идеи буду рад их заценить.
С Уважением, Александр.
Нельзя ничего сказать о глубине лужи, пока не попадешь в нее.
Re[7]: Работа с большими выборками в Windows-приложениях .NE
Здравствуйте, clon, Вы писали:
A>>Кстити, никто не пытался делать под подобную задачу кастомный DataSet, и что из этого получалось, если кто пробовал?
A>>Спасибо.
C>Недели 2 назад подобный вопрос я поднимал на многих форумах. C>Он для меня и сейчас является актуальным. C>А решение я выбралд такое: C>датасет работает в двух режимах: C>- кэшируемый (все полученные записи кэшируются) C>- оконный (кэшируется только определенное "окно" записей, но здесь возникают проблемы с представлением отдной таблицы разными вьюхами, ее я пока еще не решил).
C>Написал все свои объкты, внутрь которых положил соответсвующие объекту ADO.NET. Свойстов Count у таблиц и вьюх вытаскиваются отдельным запросом с сервера. На клиент изначально предедаются только схема БД. C>Данные закачиваются пока по требованию, но планирую делать упреждающую закачку данных. + к этому реализована еще некоторая специфичная функцианальность из-за которой и началось все это дело.
C>Если у Вас есть еще какие-либо идеи буду рад их заценить.
Александр, а как ведет себя DataView при передаче на клиента по Remoting? Он точно не сериализует вслед за собой всю исходную выборку? Если нет, то решение получается вообще супрпростое — как здесь
И мои претензии по поводу subj к маздаям сразу снимаются...
Re: Работа с большими выборками в Windows-приложениях .NET
Здравствуйте, Archistratig, Вы писали:
A>Доброе время суток всем!
A>Концептуальный вопрос.
A>Имеется тупоголовый упрямый заказчик, который настойчиво хочет, чтобы по запросу пользователя с нечетко сформированным условием выдавались все затребованные строки, даже если их окжатся миллион или более... скипнуто
Думается, надо силы бросать не на решение этой проблемы, а на уговаривание заказчика. Мы с такой проблемой столкнулись в трехуровневой системе несколько лет назад. Теперь у нас есть необсуждаемое правило — "Списки, возвращаемые на клиента, не должны быть большими. Пользователю они совершенно ни к чему! Мозг человеческий не справляется с такими объемами."
Причем можно нагло говорить пользователю — "Объем данных, которые Вы запросили, слишком велик! Сформурируйте Ваш запрос более точно."
И это так. Кроме дурацких финансовых и банковских отчетов. Реализация которых — совершенно другая песня.
Re: Работа с большими выборками в Windows-приложениях .NET
Здравствуйте, Archistratig, Вы писали:
A>Доброе время суток всем!
A>Концептуальный вопрос.
На локальных базах с Использованием Клиент-Серверной архитектуры например через Dcom это легко решается через удаленную процедуру которая перебирает все значения по условию (можно применять методы Боуер-Мур-Харрисон) с передачей направления выборки ,начального ключевого значения и количество возвращаемых строк).
С SQL тоже можно применять данный алгоритм например через ХП.
и солнце б утром не вставало, когда бы не было меня
Re[8]: Работа с большими выборками в Windows-приложениях .NE
Здравствуйте, Archistratig, Вы писали:
A>Александр, а как ведет себя DataView при передаче на клиента по Remoting? Он точно не сериализует вслед за собой всю исходную выборку?
Здравствуйте, ForestLabs, Вы писали:
FL>Здравствуйте, Archistratig, Вы писали:
A>>Доброе время суток всем!
A>>Концептуальный вопрос.
A>>Имеется тупоголовый упрямый заказчик, который настойчиво хочет, чтобы по запросу пользователя с нечетко сформированным условием выдавались все затребованные строки, даже если их окжатся миллион или более... FL>скипнуто
FL>Думается, надо силы бросать не на решение этой проблемы, а на уговаривание заказчика. Мы с такой проблемой столкнулись в трехуровневой системе несколько лет назад. Теперь у нас есть необсуждаемое правило — "Списки, возвращаемые на клиента, не должны быть большими. Пользователю они совершенно ни к чему! Мозг человеческий не справляется с такими объемами."
FL>Причем можно нагло говорить пользователю — "Объем данных, которые Вы запросили, слишком велик! Сформурируйте Ваш запрос более точно."
FL>И это так.
Готов подписаться под каждым словом.. Но легче от этого не становится.
Re[2]: Работа с большими выборками в Windows-приложениях .NE
A>Имеется тупоголовый упрямый заказчик, который настойчиво хочет
Не совсем понятно, в чём проблема. Выгрузить в DataSet данные — большой проблемы нет. В конце концов, можно в том же select'е поставить условие top 10000.
A>Да, и еще клиенское приложение должно уметь позволять редактировать данные из этой выборки.
Ну, идентификаторы в базе-то есть? По ним и редактируй.
A>Сервер БД — MS SQL,в котором Server-side курсоры
Забей на курсоры. Должна быть схема "запрос-ответ".
Естественно, пока тупоголовый упрямый заказчик прокручивает этот свой миллионный набор, данные могут измениться. Поэтому, иногда могут быть мелкие казусы. Ну тут уж, я думаю, заказчика нужно громить по чёрному. Дескать, сами хотели — вот вам и результат.
А если курсоры-шмурсоры будешь держать открытыми — точно неприятности огребёшь. Вот кто-нибудь из бухгалтерии откроет на просмотр окошко и пойдёт кофе пить, а у всё конторы тормоза. Покупатели нервничают, менеджеры по пять минут накладные распечатывают, люди скапливаются в очереди, ссорятся...
A>Заказчик согласен на организацию при доступе к таким данным paging, т.е. данные из большой выборки возвращаются кусочками фиксированного размера с возмножностью навигации между ними вперед/назад начало/конец.
Видимо, нужно примерно такой же стратегии придерживаться, как в ArrayList. Сначала загружаешь первые 10000 строк. Если мало — в каждый следующий раз умножай на два. Всё-таки, если пользователь действительно тупой, с него станется по PageDown пролистать все миллион записей.
А ещё хорошо, если набор можно посортировать по какому-нибудь полю. Тогда вообще легко загружать нужный отрезок данных "из середины", "с конца" и т.д.
A>напихивая порции в DataSet'ы (при этом снимая с его строк каким-то образом признак того, что они добавлены ручками — но это уже делали, хотя тоже неприятные)
Тю... AcceptChanges — и концы в воду. Это нормально, нечего стесняться.
... << RSDN@Home 1.1 beta 1 >>
Re[7]: Работа с большими выборками в Windows-приложениях .NE
A>>Кстати, от COUNT() толку при решении этой задачи мало. Тем более, что заранее посчитанный COUNT() может окзаться неактуальным, если кто-то успеет в промежутке межу SELECT COUNT() и SELECT выборки выполнить INSERT/DELETE.
AVK>Ну значит будет ошибка. Если она неприемлема, то в приведенной постановке задача разумными методами нерешаема.
Стопудово!
Уж тут-то на заказчика можно и нужно надавить.
... << RSDN@Home 1.1 beta 1 >>
Re[2]: Работа с большими выборками в Windows-приложениях .NE
Здравствуйте, mihailik, Вы писали:
A>>Имеется тупоголовый упрямый заказчик, который настойчиво хочет
M>Не совсем понятно, в чём проблема. Выгрузить в DataSet данные — большой проблемы нет. В конце концов, можно в том же select'е поставить условие top 10000.
В том и проблема, что по требованиям закзачика так сделать нельзя. Выбрка должна возвращать все записи по условию, а не первые N.
A>>Сервер БД — MS SQL,в котором Server-side курсоры
M>Забей на курсоры. Должна быть схема "запрос-ответ".
— при работе с выборками разумных размеров схема "запром-ответ" и никаких проблем. При описанной задаче запрос-ответ перегружает все, через что проходит ответ на этапе его обработки. Если курсоры позволяют скакать по выборке во всех направлениях, обработка такхи выборок организуется элементарно.
А я все больше склоняюсь (возвращаюсь ) к позиции ForestLab.
В клиент-серверных системах данные должны храниться и обрабатываться на сервере, а не путешествоать в процессе обработки на клиента и обратно. На клиента должны приходить только компактные результаты, исключая клинические случаи "тяжелых" отчетов. Но уж на то они и "тяжелые".
Описанная проблема возникла из реинженеринга системы, написанной много лет назад на SQL Base. Систему в свое время некий достойный человек построил на использовании скроллируемых во всех направлениях серверных курсорах. Заказчик хочет сохранить этот функционал в новой системе — отсюда и попадалово... Пробую прибить его тем, что он от старой-то отказывается в большой степени из-за того, что она все чаще и чаще падает по мере увеличения объемов данных с одновременным расширением функционала...
Хотя интересно было бы услышать мнение и противоположной стороны — аппологетов работы с большими выборками и сервер-сайдовыми курсорами. Могут ли они чем-то обосновать свою позицию, слыша со всех сторон, что делать так, как они привыкли — полный отстой?
Re[3]: Работа с большими выборками в Windows-приложениях .NE
M>>Не совсем понятно, в чём проблема. Выгрузить в DataSet данные — большой проблемы нет. В конце концов, можно в том же select'е поставить условие top 10000.
A>В том и проблема, что по требованиям закзачика так сделать нельзя. Выбрка должна возвращать все записи по условию, а не первые N.
Это уже дело клиентского приложения — собирать из кусочков.
A>>>Сервер БД — MS SQL,в котором Server-side курсоры
M>>Забей на курсоры. Должна быть схема "запрос-ответ".
A>- при работе с выборками разумных размеров схема "запром-ответ" и никаких проблем. При описанной задаче запрос-ответ перегружает все, через что проходит ответ на этапе его обработки.
Почему не делать "дозапрос" при скроллинге? Особенно, если результирующий набор сортирован — в этом случае легко сказать "top 1000" + "where MyFiled>'lastvisible'".
... << RSDN@Home 1.1 beta 1 >>
Re[4]: Работа с большими выборками в Windows-приложениях .NE
Здравствуйте, mihailik, Вы писали:
M>Почему не делать "дозапрос" при скроллинге? Особенно, если результирующий набор сортирован — в этом случае легко сказать "top 1000" + "where MyFiled>'lastvisible'".
Сортирован — это слишком строгое требование. Вся эта схема работала бы, если бы в SQL существовала конструкция не TOP <n>, а нечто вроде FROM_ROW <m> TO_ROW <n>. Эмулировать ее пратически нереально кроме специальных случаев (вроде вставить результирующую выборку в темповую таблицу с identity и мделать еще один SELECT из нее и прочая неэффективная экзотика).
M>Это уже дело клиентского приложения — собирать из кусочков.
Если б была такая конструкция — то без проблем...
А как насчет конкретных идей, как такое реализовать? Я тоже много фантазировал...