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
От: mihailik Украина  
Дата: 18.08.03 13:46
Оценка: 5 (1)
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
От: Archistratig Россия  
Дата: 19.08.03 04:45
Оценка:
Здравствуйте, 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
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 19.08.03 06:12
Оценка: 21 (5)
Здравствуйте, 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 страниц при листании грида будет только одна выборка.
... << RSDN@Home 1.1 beta 1 >>
AVK Blog
Re[8]: Работа с большими выборками в Windows-приложениях .NE
От: Archistratig Россия  
Дата: 19.08.03 06:24
Оценка:
Здравствуйте, 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 Россия http://blogs.rsdn.org/avk
Дата: 19.08.03 06:52
Оценка:
Здравствуйте, Archistratig, Вы писали:

A>Спасибо, классная идея... А запрос получается — динамический? Не очень радостно (люблю хранимые процедуры),


Можно хранимой процедурой, если заталкивать список id не в select а во временную табличку.
... << RSDN@Home 1.1 beta 1 >>
AVK Blog
Re[10]: Работа с большими выборками в Windows-приложениях .N
От: Archistratig Россия  
Дата: 19.08.03 07:07
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Archistratig, Вы писали:


A>>Спасибо, классная идея... А запрос получается — динамический? Не очень радостно (люблю хранимые процедуры),


AVK>Можно хранимой процедурой, если заталкивать список id не в select а во временную табличку.


...либо воспользоваться массивом (тем, у когоа оракул), либо таблицей (у кого M$SQL)
Re[11]: Работа с большими выборками в Windows-приложениях .N
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 19.08.03 07:22
Оценка:
Здравствуйте, Archistratig, Вы писали:

A>...либо воспользоваться массивом (тем, у когоа оракул), либо таблицей (у кого M$SQL)


В общем да, в любом случае надо мерять что быстрее. В одном случае проигрываем на времени работы парсера, в другом на транзакции и БДшную специфику.
... << RSDN@Home 1.1 beta 1 >>
AVK Blog
Re[8]: Работа с большими выборками в Windows-приложениях .NE
От: dimzon Россия http://dimzon541.narod.ru
Дата: 19.08.03 09:06
Оценка:
Здравствуйте, 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)


http://www.rsdn.ru/forum/Message.aspx?mid=306210&amp;only=1
Автор: dimzon
Дата: 24.06.03


AVK>Как правило выбирают не непосредственно с x по y, а некий фиксированногг размера кадр, чтобы уменьшить количество запросов к БД. Т.е. к примеру если кадр у тебя 4 тыс. записей, а на экран в грид влазит 20, то на каждые 200 страниц при листании грида будет только одна выборка.
... << RSDN@Home 1.1 beta 1 >>
Re[12]: Работа с большими выборками в Windows-приложениях .N
От: Archistratig Россия  
Дата: 19.08.03 09:11
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Archistratig, Вы писали:


A>>...либо воспользоваться массивом (тем, у когоа оракул), либо таблицей (у кого M$SQL)


AVK>В общем да, в любом случае надо мерять что быстрее. В одном случае проигрываем на времени работы парсера, в другом на транзакции и БДшную специфику.


Я тут покопался и нашел, что для MS SQL быстрее всего работает вариант передачи набора id в виде строки XML с последующим парсингом через OpenXML и JOIN (вместо IN). Экономия происходит за счет того, что не нужно делать N вызовов INSERT для вставки данных в темповую таблицу.

Хотел проверить вариант с передачей параметров типа таблица в хранимую процедуру через ADO .NET, но не нашел пока, как это сделать...

Кто-нибудь знает, как организовать такое вуду?
Re[7]: Работа с большими выборками в Windows-приложениях .NE
От: mihailik Украина  
Дата: 19.08.03 09:21
Оценка:
A>Блин, а если колнка a — строковая? Не годится такое рещение.

Какие проблемы со строковыми колонками — я не понял

A>ЗЫ. Кстати, не совсем понятно


Ты задавал такие вопросы, что пришлось.
... << RSDN@Home 1.1 beta 1 >>
Re[9]: Работа с большими выборками в Windows-приложениях .NE
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 19.08.03 09:42
Оценка:
Здравствуйте, dimzon, Вы писали:

D>http://www.rsdn.ru/forum/Message.aspx?mid=306210&amp;only=1
Автор: dimzon
Дата: 24.06.03


Я этот форум не читаю
... << RSDN@Home 1.1 beta 1 >>
AVK Blog
Re[13]: Работа с большими выборками в Windows-приложениях .N
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 19.08.03 09:42
Оценка:
Здравствуйте, Archistratig, Вы писали:

A>Я тут покопался и нашел, что для MS SQL быстрее всего работает вариант передачи набора id в виде строки XML с последующим парсингом через OpenXML и JOIN (вместо IN).


А с чем сравнивал? А тесты и результаты можно в студию?

A> Экономия происходит за счет того, что не нужно делать N вызовов INSERT для вставки данных в темповую таблицу.


А их не надо делать раздельно, надо формировать один запрос с кучей insert и отправлять его целиком.
... << RSDN@Home 1.1 beta 1 >>
AVK Blog
Re[5]: Работа с большими выборками в Windows-приложениях .NE
От: Alex Warm Россия  
Дата: 09.09.03 07:34
Оценка: 10 (3)
Здравствуйте, 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
От: Banch  
Дата: 09.09.03 15:48
Оценка:
AW>Если-же в нем есть каки-то недостатки — хотелось-бы о них услышать.

посмотрел в соседнем форуме про БД, там говорят что при большом количестве записей будет тормозить
я у себя проверил, на 10000 работает отлично
(конечно нужно сделать индекс по сортируемой колонке)

спасибо за такой интересный способ постраничной выборки!
Re[6]: Работа с большими выборками в Windows-приложениях .NE
От: ClsProgramming  
Дата: 12.03.06 03:15
Оценка:
Здравствуйте, 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
От: Sinclair Россия https://github.com/evilguest/
Дата: 15.03.06 05:12
Оценка: +1
Здравствуйте, Archistratig, Вы писали:
A>В том и проблема, что по требованиям закзачика так сделать нельзя. Выбрка должна возвращать все записи по условию, а не первые N.
Нет такого требования. Требования заказчика могут касаться только того, что видно на экране. Поскольку в задаче фигурирует пейджинг, то никто не сможет определить, были ли в действительности переданы все миллионы записей в приложение. Достаточно отдельно сделать запрос select count * from ..., чтобы написать полное количество записей.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Работа с большими выборками в Windows-приложениях .NE
От: Ryf  
Дата: 15.03.06 07:28
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Archistratig, Вы писали:

A>>В том и проблема, что по требованиям закзачика так сделать нельзя. Выбрка должна возвращать все записи по условию, а не первые N.
S>Нет такого требования. Требования заказчика могут касаться только того, что видно на экране. Поскольку в задаче фигурирует пейджинг, то никто не сможет определить, были ли в действительности переданы все миллионы записей в приложение. Достаточно отдельно сделать запрос select count * from ..., чтобы написать полное количество записей.
Так бывает когда заказчик сам давно когда-то программил, он то видел, он тут знает ... С такими труднее всего...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.