Re[2]: Чтение больших выборок данных частями
От: MozgC США http://nightcoder.livejournal.com
Дата: 23.03.16 15:28
Оценка:
Здравствуйте, Softwarer, Вы писали:

N_P>>Сам пока остановился на Select Top 1000 * Where ... AND ID > LastID Order by ID и чтении порциями

S>То есть Вам абсолютно пофиг, что ваш запрос вернёт левую мешанину неконсистентных данных. Или Вы соответственно подняли уровень изоляции?

Вы про то что надо добавить AND ID <= MAXID или про какую-то другую проблему?
Re: Чтение больших выборок данных частями
От: MozgC США http://nightcoder.livejournal.com
Дата: 23.03.16 15:40
Оценка:
Что вы делаете с этим миллионом строк после чтения из базы? Можно ли эту логику перенести на БД? Можно ли обрабатывать данные поточно?

Вообще, если у вас выборка миллиона записей выполняется непозволительно долго, то сходу возникают такие варианты:
1) Попробовать читать и обрабатывать в несколько потоков.
2) Оптимизировать БД.
3) Попробовать делать эту обработку заранее на application server'е.
Re[2]: Чтение больших выборок данных частями
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 23.03.16 15:53
Оценка: +1
Здравствуйте, vsb, Вы писали:

vsb>Третий вариант — аналог mysql-ного limit 3000, 1000, в каждой базе по-своему пишется. Это самый плохой вариант, т.к. база должна внутри себя выполнить весь запрос и потом вернуть нужный кусок. Хотя для небольших выборок подходит.


Я не уверен, что это самый плохой вариант. Его правда надо немного модифицировать — поставить в запросе ORDER BY по индексированному полю (например ID, primary key), а начало вычислять по условию WHERE (например, id > last_id). В этом случае база не должна выполнять весь запрос. Достаточно найти первую запись, далее, двигаясь по индексу, последовательно насобирать нужное количество строк.
Re[5]: Чтение больших выборок данных частями
От: wildwind Россия  
Дата: 24.03.16 07:41
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>Библиотеки, которыми я пользуюсь для решения этой задачи (как раз пейджинг и реализуют) есть только под C# ADO.NET.


А твое приложение что, для доступа к БД использует и другие фреймворки, кроме ADO.NET? Я все еще не вижу проблемы.

N_P>Так проблема в том, что никто не знает времени исполнения произвольного запроса до его исполнения. Мы не можем настроить правильный таймаут заранее. Мы можем сделать его разумно большим, но в этом — свои неприятности. Подробнее — ниже.


Если для выполнения запроса СУБД нужен час, то таймаут для этого запроса должен быть не меньше часа. По-моему это очевидно. Для большинства запросов таймаут вообще не стоит ставить. Таймаут ставят там, где гарантированное время отклика важнее даже получения результата.

N_P>Именно этот вариант сейчас в работе. Правда, на сторонних библиотеках. Есть ли варианты кроме пейджинга? Какие есть варианты read only forward only paging?


Альтернатива — просто выполнить запрос и читать строки результата такими порциями, как тебе удобно.

N_P>Проблема — управляемое чтение больших массивов данных. Не в смысле количества байт, а в смысле числа строк. И мне показалось изначально разумным, что все сразу мы не получим и запрос будет разбит на подзапросы. Именно из-за требования больших таймаутов для исполнения большого запроса.


OK, если проблема в таймауте, убери таймаут совсем и нет проблемы.

N_P>Потому что практика показывает, что большой таймаут несет проблемы с реакцией оператора (не только в GUI), трудностями в отмене операции, трудностями в реагировании на сбои (понять, что отвалился сервер желательно как можно раньше, а у нас таймаут — час), трудностями с блокировкой ресурсов БД и отъеданием ресурсов сервера БД.


Это все общие слова. Приведи конкретный сценарий (не надуманный) с конкретной проблемой, можно обсудить.

Насчет "отвалился сервер". Еще раз — если запрос выполняется час, значит нужно ждать час, ничего с этим не поделаешь (кроме оптимизации). И не нужно мешать серверу таймаутами. Понимать "как можно раньше" — это не твоя задача, как разработчика; это задача DBA. И у них есть свои инструменты для этого. Некоторые СУБД даже предоставляют API для отслеживания прогресса выполнения конкретных "долгоиграющих" запросов. Но они опять же, для админов.

На этапе же выборки результата управление полностью на твоей стороне и вышеописанных проблем нет.

N_P>Курсоры, как учат нас книги и интернет — вселенское тормозное зло. Что применять?


Еще одна догма? Выкинь. Применяй голову.
Re[2]: Чтение больших выборок данных частями
От: kov_serg Россия  
Дата: 24.03.16 23:01
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Что вы делаете с этим миллионом строк после чтения из базы? Можно ли эту логику перенести на БД? Можно ли обрабатывать данные поточно?


MC>Вообще, если у вас выборка миллиона записей выполняется непозволительно долго, то сходу возникают такие варианты:

MC>1) Попробовать читать и обрабатывать в несколько потоков.
MC>2) Оптимизировать БД.
MC>3) Попробовать делать эту обработку заранее на application server'е.

4) https://en.wikipedia.org/wiki/Shard_%28database_architecture%29
http://ruhighload.com/post/%D0%93%D0%BE%D1%80%D0%B8%D0%B7%D0%BE%D0%BD%D1%82%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9+%D1%88%D0%B0%D1%80%D0%B4%D0%B8%D0%BD%D0%B3
Re[3]: Чтение больших выборок данных частями
От: Sinclair Россия https://github.com/evilguest/
Дата: 08.04.16 12:07
Оценка:
Здравствуйте, MozgC, Вы писали:

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


N_P>>>Сам пока остановился на Select Top 1000 * Where ... AND ID > LastID Order by ID и чтении порциями

S>>То есть Вам абсолютно пофиг, что ваш запрос вернёт левую мешанину неконсистентных данных. Или Вы соответственно подняли уровень изоляции?

MC>Вы про то что надо добавить AND ID <= MAXID или про какую-то другую проблему?

Про то, что между 1й и второй страницами могли вклиниться произвольное количество операций DELETE и INSERT.
Простейшая штука — строка 999 отдаётся с ID=999, а строка 1000 — c ID=2000.
Вы выполняете Select Top 1000 * Where ... AND ID > 2000 Order by ID , но перед этим кто-то сделал 1000 insert c ID = 1000, 1001, ..., 1999.
А вы их так и не увидели, потому что >2000.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Чтение больших выборок данных частями
От: IB Австрия http://rsdn.ru
Дата: 09.04.16 19:31
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Вы выполняете Select Top 1000 * Where ... AND ID > 2000 Order by ID , но перед этим кто-то сделал 1000 insert c ID = 1000, 1001, ..., 1999.

S>А вы их так и не увидели, потому что >2000.
Справедливости ради надо заметить, что с практической точки зрения, не имеет никакого значения в какой момент произошел этот insert. Он с тем же успехом мог произойти и после того как на клиент уехала вся выборка... Так что history этих транзакций вполне serializable. В определенном смысле такой запрос — аналог снапшота. =)
Другое дело, если бы было две дырки, скажем 999...2000 и 2999...4000, и кто-то сделал insert с ID 1000 и 3000. И при этом для первой транзакции по какой-то причине важно, чтобы в выборку попали либо оба этих значения, либо ни одного. Вот тогда да — были бы проблемы...
Но на практике это крайне редкий сценарий, особенно если речь идет о постраничной выборке.
Мы уже победили, просто это еще не так заметно...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.