Имеется тупоголовый упрямый заказчик, который настойчиво хочет, чтобы по запросу пользователя с нечетко сформированным условием выдавались все затребованные строки, даже если их окжатся миллион или более... Результаты должны отображаться в 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>Это уже дело клиентского приложения — собирать из кусочков.
Если б была такая конструкция — то без проблем...
А как насчет конкретных идей, как такое реализовать? Я тоже много фантазировал...
Re[5]: Работа с большими выборками в Windows-приложениях .NE
От:
Аноним
Дата:
16.08.03 10:05
Оценка:
Здравствуйте, Archistratig, Вы писали:
A>Сортирован — это слишком строгое требование. Вся эта схема работала бы, если бы в SQL существовала конструкция не TOP <n>, а нечто вроде FROM_ROW <m> TO_ROW <n>. Эмулировать ее пратически нереально кроме специальных случаев (вроде вставить результирующую выборку в темповую таблицу с identity и мделать еще один SELECT из нее и прочая неэффективная экзотика).
На самом деле такой подход показывает себя довольно эффективным.
Первые страницы открываются _намного_ быстрее, чем при использовании серверных курсоров, и смею уверить что большинству пользователей первой страницы будет достаточно.
В добавок, если используются в запросов сортировки то это зачастую приводит к неявному созданию временных таблиц.
A>А как насчет конкретных идей, как такое реализовать? Я тоже много фантазировал...
Re[5]: Работа с большими выборками в Windows-приложениях .NE
A>Сортирован — это слишком строгое требование. Вся эта схема работала бы, если бы в SQL существовала конструкция не TOP <n>, а нечто вроде FROM_ROW <m> TO_ROW <n>.
По-моему как раз твоя конструкция — слишком строгое требование. Её в MS SQL не вставишь. А сортировать по любому, хоть по первому полю всё-таки проще.
M>>Это уже дело клиентского приложения — собирать из кусочков.
A>Если б была такая конструкция — то без проблем...
Да нет, с сортировкой тоже без проблем.
Сначала вызываем посчитать count(*). Потом клиентское приложение посылает для первой порции запрос:
select top 100 a,b,c from tab1 order by a
Вкачивает результат в свой буфёр и показывает: всего столько-то записей, вот вам первые 100.
Если теперь пользователь хочет следующие — посылаем запрос:
select top 100 a,b,c from tab1 where a>='последнее предыдущее значение'order by a
Вкачиваем результат, добавляем во внутренний буфер. Естественно, отрабатываем строки-пересечения, то есть выкидываем дубли, возникшие от двух запросов.
Для перехода в конец — order by/desc использовать.
Естественно, нельзя перейти в произвольную часть — только PgUp/PgDown и Home/End.
... << RSDN@Home 1.1 beta 1 >>
Re[6]: Работа с большими выборками в Windows-приложениях .NE
Здравствуйте, mihailik, Вы писали:
M>Да нет, с сортировкой тоже без проблем.
M>Сначала вызываем посчитать count(*). Потом клиентское приложение посылает для первой порции запрос:
M>
M>select top 100 a,b,c from tab1 order by a
M>
M>Вкачивает результат в свой буфёр и показывает: всего столько-то записей, вот вам первые 100.
M>Если теперь пользователь хочет следующие — посылаем запрос: M>
M>select top 100 a,b,c from tab1 where a>='последнее предыдущее значение'order by a
M>
M>Вкачиваем результат, добавляем во внутренний буфер. Естественно, отрабатываем строки-пересечения, то есть выкидываем дубли, возникшие от двух запросов.
M>Для перехода в конец — order by/desc использовать.
M>Естественно, нельзя перейти в произвольную часть — только PgUp/PgDown и Home/End.
Блин, а если колнка a — строковая? Не годится такое рещение.
ЗЫ. Кстати, не совсем понятно, зачем с такой маниакальной настойчивостью жевать банальные вещи... ИМХО, с первого постинга на тему "select top 100" понятен предлагаемый алгоритм, видны все его достоинства и недостатки...
Re[7]: Работа с большими выборками в Windows-приложениях .NE
Здравствуйте, Archistratig, Вы писали:
A>ЗЫ. Кстати, не совсем понятно, зачем с такой маниакальной настойчивостью жевать банальные вещи... ИМХО, с первого постинга на тему "select top 100" понятен предлагаемый алгоритм, видны все его достоинства и недостатки...
Все таки последнее время алгоритмы для больших выборок пользуют несколько иные, по крайней мере на серверах приложений. При этом обычно в память выбирают все PK записей выборки, а при листании покадрово вытаскивают уже собственно саму выборку. Т.е. сначала делают такой запрос
select id from some_table where <condition>
Далее мы уже имеет как минимум COUNT, т.е. можем нормально позиционировать скроллер, при этом затраты памяти не сильно велики, count*4 при автоинкрементном pk, count*16 при guid pk. Далее при запросе записей с x по y выбирают собственно записи
select * from some_table where id in (список идентификаторов кадра, определенных по первой выборке в позициях между x и y)
Как правило выбирают не непосредственно с x по y, а некий фиксированногг размера кадр, чтобы уменьшить количество запросов к БД. Т.е. к примеру если кадр у тебя 4 тыс. записей, а на экран в грид влазит 20, то на каждые 200 страниц при листании грида будет только одна выборка.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Archistratig, Вы писали:
AVK>select id from some_table where <condition>
AVK>Далее мы уже имеет как минимум COUNT, т.е. можем нормально позиционировать скроллер, при этом затраты памяти не сильно велики, count*4 при автоинкрементном pk, count*16 при guid pk. Далее при запросе записей с x по y выбирают собственно записи
AVK>select * from some_table where id in (список идентификаторов кадра, определенных по первой выборке в позициях между x и y)
Спасибо, классная идея... А запрос получается — динамический? Не очень радостно (люблю хранимые процедуры), но — приятно. Память конкретно экономится.
Re[9]: Работа с большими выборками в Windows-приложениях .NE
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Archistratig, Вы писали:
A>>Спасибо, классная идея... А запрос получается — динамический? Не очень радостно (люблю хранимые процедуры),
AVK>Можно хранимой процедурой, если заталкивать список id не в select а во временную табличку.
...либо воспользоваться массивом (тем, у когоа оракул), либо таблицей (у кого M$SQL)
Re[11]: Работа с большими выборками в Windows-приложениях .N
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Archistratig, Вы писали:
A>>ЗЫ. Кстати, не совсем понятно, зачем с такой маниакальной настойчивостью жевать банальные вещи... ИМХО, с первого постинга на тему "select top 100" понятен предлагаемый алгоритм, видны все его достоинства и недостатки...
AVK>Все таки последнее время алгоритмы для больших выборок пользуют несколько иные, по крайней мере на серверах приложений. При этом обычно в память выбирают все PK записей выборки, а при листании покадрово вытаскивают уже собственно саму выборку. Т.е. сначала делают такой запрос
AVK>select id from some_table where <condition>
AVK>Далее мы уже имеет как минимум COUNT, т.е. можем нормально позиционировать скроллер, при этом затраты памяти не сильно велики, count*4 при автоинкрементном pk, count*16 при guid pk. Далее при запросе записей с x по y выбирают собственно записи
AVK>select * from some_table where id in (список идентификаторов кадра, определенных по первой выборке в позициях между x и y)
AVK>Как правило выбирают не непосредственно с x по y, а некий фиксированногг размера кадр, чтобы уменьшить количество запросов к БД. Т.е. к примеру если кадр у тебя 4 тыс. записей, а на экран в грид влазит 20, то на каждые 200 страниц при листании грида будет только одна выборка.
... << RSDN@Home 1.1 beta 1 >>
Re[12]: Работа с большими выборками в Windows-приложениях .N
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Archistratig, Вы писали:
A>>...либо воспользоваться массивом (тем, у когоа оракул), либо таблицей (у кого M$SQL)
AVK>В общем да, в любом случае надо мерять что быстрее. В одном случае проигрываем на времени работы парсера, в другом на транзакции и БДшную специфику.
Я тут покопался и нашел, что для MS SQL быстрее всего работает вариант передачи набора id в виде строки XML с последующим парсингом через OpenXML и JOIN (вместо IN). Экономия происходит за счет того, что не нужно делать N вызовов INSERT для вставки данных в темповую таблицу.
Хотел проверить вариант с передачей параметров типа таблица в хранимую процедуру через ADO .NET, но не нашел пока, как это сделать...
Кто-нибудь знает, как организовать такое вуду?
Re[7]: Работа с большими выборками в Windows-приложениях .NE
Здравствуйте, Archistratig, Вы писали:
A>Я тут покопался и нашел, что для MS SQL быстрее всего работает вариант передачи набора id в виде строки XML с последующим парсингом через OpenXML и JOIN (вместо IN).
А с чем сравнивал? А тесты и результаты можно в студию?
A> Экономия происходит за счет того, что не нужно делать N вызовов INSERT для вставки данных в темповую таблицу.
А их не надо делать раздельно, надо формировать один запрос с кучей insert и отправлять его целиком.
Здравствуйте, Archistratig!
Давненько я тут не появлялся, но было время когда Вы писали:
A>Сортирован — это слишком строгое требование. Вся эта схема работала бы, если бы в SQL существовала конструкция не TOP <n>, а нечто вроде FROM_ROW <m> TO_ROW <n>. Эмулировать ее пратически нереально кроме специальных случаев (вроде вставить результирующую выборку в темповую таблицу с identity и мделать еще один SELECT из нее и прочая неэффективная экзотика).
Когда-то я тоже сталкивался с такой проблеммой. Добрые люди подсказали решение.
К примеру P — номер страницы
N — количество записей на странице
тогда получается следующая картина для 5 страницы из 20 записей
select * from
(select top 20 * from
(select top 100 * from tbl order by tbl_id) as tmp1
order by tmp1.tbl_id desc) as tmp2
order by tmp2.tbl_id
На выходе получится именно то, что вы и хотели <from 80 to 100>
Возможно этот метод вы отнесете к "неэффективной экзотике", но лично меня этот метод устраивает.
Если-же в нем есть каки-то недостатки — хотелось-бы о них услышать.
... << RSDN@Home 1.1 beta 2 >>
Re[6]: Работа с большими выборками в Windows-приложениях .NE
AW>Если-же в нем есть каки-то недостатки — хотелось-бы о них услышать.
посмотрел в соседнем форуме про БД, там говорят что при большом количестве записей будет тормозить
я у себя проверил, на 10000 работает отлично
(конечно нужно сделать индекс по сортируемой колонке)
спасибо за такой интересный способ постраничной выборки!
Re[6]: Работа с большими выборками в Windows-приложениях .NE
Здравствуйте, Alex Warm, Вы писали:
AW>Когда-то я тоже сталкивался с такой проблеммой. Добрые люди подсказали решение. AW>К примеру P — номер страницы AW>N — количество записей на странице AW>тогда получается следующая картина для 5 страницы из 20 записей AW>
AW>select * from
AW>(select top 20 * from
AW>(select top 100 * from tbl order by tbl_id) as tmp1
AW>order by tmp1.tbl_id desc) as tmp2
AW>order by tmp2.tbl_id
AW>
AW>На выходе получится именно то, что вы и хотели <from 80 to 100> AW>Возможно этот метод вы отнесете к "неэффективной экзотике", но лично меня этот метод устраивает. AW>Если-же в нем есть каки-то недостатки — хотелось-бы о них услышать.
Метод — супер. Спасибо. Оценил.
Re[3]: Работа с большими выборками в Windows-приложениях .NE
Здравствуйте, Archistratig, Вы писали: A>В том и проблема, что по требованиям закзачика так сделать нельзя. Выбрка должна возвращать все записи по условию, а не первые N.
Нет такого требования. Требования заказчика могут касаться только того, что видно на экране. Поскольку в задаче фигурирует пейджинг, то никто не сможет определить, были ли в действительности переданы все миллионы записей в приложение. Достаточно отдельно сделать запрос select count * from ..., чтобы написать полное количество записей.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Работа с большими выборками в Windows-приложениях .NE
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Archistratig, Вы писали: A>>В том и проблема, что по требованиям закзачика так сделать нельзя. Выбрка должна возвращать все записи по условию, а не первые N. S>Нет такого требования. Требования заказчика могут касаться только того, что видно на экране. Поскольку в задаче фигурирует пейджинг, то никто не сможет определить, были ли в действительности переданы все миллионы записей в приложение. Достаточно отдельно сделать запрос select count * from ..., чтобы написать полное количество записей.
Так бывает когда заказчик сам давно когда-то программил, он то видел, он тут знает ... С такими труднее всего...