Чтение больших выборок данных частями
От: Nikolay_P_I  
Дата: 21.03.16 06:28
Оценка: :)
Есть задача: Дается Select * Where .... с результатом около миллиона. Задача — выполнить запрос и прочитать данные.

БД MS SQL, но интересно так же и академическое решение.

"В лоб" решить не получится: в память приложения все не влезет, да и по времени таймаут будет.

Как принято решать такие вопросы ?

Сам пока остановился на Select Top 1000 * Where ... AND ID > LastID Order by ID и чтении порциями
Re: Чтение больших выборок данных частями
От: kov_serg Россия  
Дата: 21.03.16 06:41
Оценка: -1
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>Есть задача: Дается Select * Where .... с результатом около миллиона. Задача — выполнить запрос и прочитать данные.

И с большим количеством можно работать.
А вообще сесть хранимые процедуры.

N_P>БД MS SQL, но интересно так же и академическое решение.

Скорее всего вы решаете задачу не стого конца.

N_P>"В лоб" решить не получится: в память приложения все не влезет, да и по времени таймаут будет.

А зачем вы все это пихаете в память?

N_P>Как принято решать такие вопросы ?

Обычно принято думать.

N_P>Сам пока остановился на Select Top 1000 * Where ... AND ID > LastID Order by ID и чтении порциями
Re: Чтение больших выборок данных частями
От: Dym On Россия  
Дата: 21.03.16 06:50
Оценка:
N_P>Есть задача: Дается Select * Where .... с результатом около миллиона. Задача — выполнить запрос и прочитать данные.
Нет, это не задача, это первый шаг одного из способов решения задачи. Так какая же задача? Что надо сделать с данными?
Счастье — это Glück!
Re: Чтение больших выборок данных частями
От: wildwind Россия  
Дата: 21.03.16 07:05
Оценка: +1
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>"В лоб" решить не получится: в память приложения все не влезет, да и по времени таймаут будет.


А зачем все в память? Обрабатывай поточно. Таймауты настраиваются, в т.ч. программно.

N_P>Как принято решать такие вопросы ?


1. Обрабатывать на сервере (с помощью SQL или ХП).
2. Обрабатывать на клиенте, не помещая все в память.

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


И такой способ применяется, если можно обеспечить согласованность частей.
Re: Чтение больших выборок данных частями
От: Softwarer http://softwarer.ru
Дата: 21.03.16 07:45
Оценка: +2
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>БД MS SQL, но интересно так же и академическое решение.


Академически такие задачи не решаются (вернее — решаются недопустимо плохо).

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


То есть Вам абсолютно пофиг, что ваш запрос вернёт левую мешанину неконсистентных данных. Или Вы соответственно подняли уровень изоляции?
Re[2]: Чтение больших выборок данных частями
От: Nikolay_P_I  
Дата: 21.03.16 08:13
Оценка: +1 -2
Здравствуйте, kov_serg, Вы писали:

N_P>>Как принято решать такие вопросы ?

_>Обычно принято думать.

Здесь как то лет пять назад хорошо сказали про отличие наших форумов от зарубежных. Если кратно — "Там помогут даже полному нубу, а у нас — растопырят пальцы и пошлют. В лучшем случае на RTFM".
Re[2]: Чтение больших выборок данных частями
От: Nikolay_P_I  
Дата: 21.03.16 08:18
Оценка: -1
Здравствуйте, Softwarer, Вы писали:

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

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

В данном случае не важно. Проблемы адекватности данных решаются бизнес-логикой.
Re[2]: Чтение больших выборок данных частями
От: Nikolay_P_I  
Дата: 21.03.16 08:23
Оценка:
Здравствуйте, Dym On, Вы писали:

N_P>>Есть задача: Дается Select * Where .... с результатом около миллиона. Задача — выполнить запрос и прочитать данные.

DO>Нет, это не задача, это первый шаг одного из способов решения задачи. Так какая же задача? Что надо сделать с данными?

Так она такая и есть — Пользователь делает запрос, программа получает данные от БД, делает легкую обработку и выводит результат наружу, например, в файл.
Дополнительные условия: MS SQL Server, C#, возможность cancel операции. Правка БД (вставка своих SP) возможна, но не желательна.
Re[3]: Чтение больших выборок данных частями
От: Qulac Россия  
Дата: 21.03.16 08:33
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>Здравствуйте, Dym On, Вы писали:


N_P>>>Есть задача: Дается Select * Where .... с результатом около миллиона. Задача — выполнить запрос и прочитать данные.

DO>>Нет, это не задача, это первый шаг одного из способов решения задачи. Так какая же задача? Что надо сделать с данными?

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

N_P>Дополнительные условия: MS SQL Server, C#, возможность cancel операции. Правка БД (вставка своих SP) возможна, но не желательна.

Так Вас что смущает, миллион записей в памяти это не много.
Программа – это мысли спрессованные в код
Re[3]: Чтение больших выборок данных частями
От: Dym On Россия  
Дата: 21.03.16 08:35
Оценка:
DO>>Нет, это не задача, это первый шаг одного из способов решения задачи. Так какая же задача? Что надо сделать с данными?
N_P>Так она такая и есть — Пользователь делает запрос, программа получает данные от БД, делает легкую обработку и выводит результат наружу, например, в файл.
О, вывод данных в файл. Bulk copy program? Или есть что-то еще? Легкая обработка это что?
Счастье — это Glück!
Re[2]: Чтение больших выборок данных частями
От: Nikolay_P_I  
Дата: 21.03.16 08:39
Оценка:
Здравствуйте, wildwind, Вы писали:

N_P>>"В лоб" решить не получится: в память приложения все не влезет, да и по времени таймаут будет.

W>А зачем все в память? Обрабатывай поточно. Таймауты настраиваются, в т.ч. программно.

Поточно — не нравится привязка к framework, с которым с БД работаю (сейчас C# ADO.NET). А таймауты расширять дело плохое. Или на большой запрос времени не хватит или посыпятся жалобы на то, что при отвале БД об ошибке программа сообщит только через полчаса.

Вообще — я почему именно сюда, а не в .NET тему, такой вопрос написал? Я подумал, что дело это, чтение больших выборок, не редкое, те же grid для вывода больших данных есть аналогичная задача. И что есть уже наработанные и проверенные паттерны этой задачи решения.

В принципе, ответ в виде "общего решения нет, только БД и framework-ориентированные" тоже ответ.

N_P>>Как принято решать такие вопросы ?


W>1. Обрабатывать на сервере (с помощью SQL или ХП).

А как? Что по этому поводу почитать и где посмотреть пример?

W>2. Обрабатывать на клиенте, не помещая все в память.

В память вполне можно получить полный ID записей.
Re: Чтение больших выборок данных частями
От: vsb Казахстан  
Дата: 21.03.16 08:42
Оценка:
Любой интерфейс к БД, по крайней мере те, которые я видел, читают данные по строкам. Внутри они подгружают данные кусками, конечно, чтобы не гонять по сокету лишний раз данные, но точно не всё. Поэтому проблемы чтения больших выборок частями нет в принципе. Читайте построчно и делайте что хотите.

Если вопрос в том, чтобы именно выбрать данные кусками, то лучше всего использовать выборку по столбцу, например хорошо подходит автоинкрементный столбец ID. Выбираете where id between 1 and 1000 и вот вам первые 1000 записей (если есть удаления, то примерно 1000 записей). Чаще всего это самый лучший путь, слегка жертвуете точностью, зато запрос для БД просто идеальный.

Второй вариант — делаете запрос на N+1 запись, упорядоченный по id и читаете его. Если вернуло меньше записей, значит больше записей нет, иначе запоминаете id последней записи и в следующий раз делаете запрос начиная с этого id. В этом случае будут возвращаться ровно n записей, будет возможность перемещаться по результатам вперёд и назад и для БД всё будет хорошо, но вот в приложении такое программировать очень муторно.

Третий вариант — аналог mysql-ного limit 3000, 1000, в каждой базе по-своему пишется. Это самый плохой вариант, т.к. база должна внутри себя выполнить весь запрос и потом вернуть нужный кусок. Хотя для небольших выборок подходит.
Re[4]: Чтение больших выборок данных частями
От: Nikolay_P_I  
Дата: 21.03.16 09:02
Оценка:
Здравствуйте, Dym On, Вы писали:

DO>>>Нет, это не задача, это первый шаг одного из способов решения задачи. Так какая же задача? Что надо сделать с данными?

N_P>>Так она такая и есть — Пользователь делает запрос, программа получает данные от БД, делает легкую обработку и выводит результат наружу, например, в файл.
DO>О, вывод данных в файл. Bulk copy program? Или есть что-то еще? Легкая обработка это что?

Нет. Файл чисто для примера. Реально там считается некая математика, а потом все это рассылается по RabbitMQ службам-клиентам. Просто для задачи про БД это уже не важно.
Re[4]: Чтение больших выборок данных частями
От: Nikolay_P_I  
Дата: 21.03.16 09:07
Оценка:
Здравствуйте, Qulac, Вы писали:

N_P>>Так она такая и есть — Пользователь делает запрос, программа получает данные от БД, делает легкую обработку и выводит результат наружу, например, в файл. N_P>>Дополнительные условия: MS SQL Server, C#, возможность cancel операции. Правка БД (вставка своих SP) возможна, но не желательна.


Q>Так Вас что смущает, миллион записей в памяти это не много.


Да я знаю, а если только ID записей запрашивать — так и вообще считанные мегабайты. Просто исполнение долгого запроса разом очень неудобно — таймаут большой вреден, отмена от пользователя не всегда возможна, ресурсы БД блокируются и сама БД притормаживает.

Вот и хочу узнать — какие есть паттерны решения таких задач. Мыслей-то много, типа SP с созданием временной таблицы с ID результатов, а потом из нее читать — но это тоже с недостатками. Зачем писать очередной велосипед?
Re: Чтение больших выборок данных частями
От: Olaf Россия  
Дата: 21.03.16 09:14
Оценка: +1
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>"В лоб" решить не получится: в память приложения все не влезет, да и по времени таймаут будет.


N_P>Как принято решать такие вопросы ?


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


Можно читать данные равными частями, т.е. страницами с использованием в MS SQL Server 2012+ инструкции offset fetch, но за согласованность данных вы конечно отвечаете самостоятельно. Для версий ниже 2012 стоит рассмотреть альтернативные варианты реализации paging.

-- Skip 0 rows and return only the first 10 rows from the sorted result set.
SELECT DepartmentID, Name, GroupName
FROM HumanResources.Department
ORDER BY DepartmentID 
    OFFSET 0 ROWS
    FETCH NEXT 10 ROWS ONLY;
Re[3]: Чтение больших выборок данных частями
От: kov_serg Россия  
Дата: 21.03.16 12:47
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

W>>1. Обрабатывать на сервере (с помощью SQL или ХП).

N_P>А как? Что по этому поводу почитать и где посмотреть пример?
ftp://46.39.237.103/McGraw.Hill.Microsoft.SQL.Server.2005.Stored.Procedure.Programming.in.T-SQL.and.dot.NET.3rd.Edition.May.2006.chm
Re[2]: Чтение больших выборок данных частями
От: Milena США  
Дата: 21.03.16 15:42
Оценка: +3 -1
Здравствуйте, kov_serg, Вы писали:

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


N_P>>Есть задача: Дается Select * Where .... с результатом около миллиона. Задача — выполнить запрос и прочитать данные.

_>И с большим количеством можно работать.
_>А вообще сесть хранимые процедуры.

N_P>>БД MS SQL, но интересно так же и академическое решение.

_>Скорее всего вы решаете задачу не стого конца.

N_P>>"В лоб" решить не получится: в память приложения все не влезет, да и по времени таймаут будет.

_>А зачем вы все это пихаете в память?

N_P>>Как принято решать такие вопросы ?

_>Обычно принято думать.
Человек подумал и пока не придумал. И попросил помощи. Этот форум, чтобы найти помощь, а не чтобы послушать, какой вы якобы умный... Заметьте, вы тут много сказали "А вообще сесть хранимые процедуры." и "Скорее всего вы решаете задачу не стого конца". По делу — 0. Так может напишите подробно, как использовать хранимки, чтобы не пихать в память и сделать постраничную выборку при необходимости показать данные пользователю?
Re[3]: Чтение больших выборок данных частями
От: wildwind Россия  
Дата: 21.03.16 16:06
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>Поточно — не нравится привязка к framework, с которым с БД работаю (сейчас C# ADO.NET).


Поясни, пожалуйста, о какой привязке идет речь.

N_P>А таймауты расширять дело плохое. Или на большой запрос времени не хватит или посыпятся жалобы на то, что при отвале БД об ошибке программа сообщит только через полчаса.


Никто же не предлагает один таймаут на все случаи жизни, будь он большим или маленьким. Они для того и настраиваются, чтобы применять их разумно, по ситуации.

N_P>Вообще — я почему именно сюда, а не в .NET тему, такой вопрос написал? Я подумал, что дело это, чтение больших выборок, не редкое, те же grid для вывода больших данных есть аналогичная задача. И что есть уже наработанные и проверенные паттерны этой задачи решения.


Большая выборка в гриде — это совсем другой случай. Как правило, это свидетельство неумелого проектирования UI. Но для остальных случаев проверенный паттерн — это пейджинг, с разными способами и степенью его поддержки в СУБД и фреймворках.

N_P>В принципе, ответ в виде "общего решения нет, только БД и framework-ориентированные" тоже ответ.


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

W>>1. Обрабатывать на сервере (с помощью SQL или ХП).

N_P>А как? Что по этому поводу почитать и где посмотреть пример?

Зависит от задачи и алгоритма. Если конечным результатом обработки миллиона строк является тысяча строк или сотня, то лучше сделать это на сервере, поближе к исходным данным, чтобы не тратить время на перекачку их по сети. Конечная выборка получится уже небольшая.

Почитать — документацию по СУБД, там и примеры есть. Ну и на книжку вон ссылку уже кинули.

W>>2. Обрабатывать на клиенте, не помещая все в память.

N_P>В память вполне можно получить полный ID записей.

Не понял?
Re[4]: Чтение больших выборок данных частями
От: Nikolay_P_I  
Дата: 23.03.16 10:30
Оценка:
Здравствуйте, wildwind, Вы писали:

N_P>>Поточно — не нравится привязка к framework, с которым с БД работаю (сейчас C# ADO.NET).

W>Поясни, пожалуйста, о какой привязке идет речь.

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

N_P>>А таймауты расширять дело плохое. Или на большой запрос времени не хватит или посыпятся жалобы на то, что при отвале БД об ошибке программа сообщит только через полчаса.

W>Никто же не предлагает один таймаут на все случаи жизни, будь он большим или маленьким. Они для того и настраиваются, чтобы применять их разумно, по ситуации.

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

N_P>>Вообще — я почему именно сюда, а не в .NET тему, такой вопрос написал? Я подумал, что дело это, чтение больших выборок, не редкое, те же grid для вывода больших данных есть аналогичная задача. И что есть уже наработанные и проверенные паттерны этой задачи решения.

W>Большая выборка в гриде — это совсем другой случай. Как правило, это свидетельство неумелого проектирования UI. Но для остальных случаев проверенный паттерн — это пейджинг, с разными способами и степенью его поддержки в СУБД и фреймворках.

Именно этот вариант сейчас в работе. Правда, на сторонних библиотеках. Есть ли варианты кроме пейджинга? Какие есть варианты read only forward only paging? Зря я, наверное, слишком общий вопрос задал — спросил бы сразу про виды и альтернативы пейджингу.

W>Для меня все еще непонятна проблема, для которой ищется "общее решение". Если ты где-то услышал или прочитал мантру "долгие запросы это очень плохо, нужно их избегать или бить на части", то не нужно воспринимать ее как догму, а оценивать с умом по конкретной ситуации. Для интерактивной работы да, это плохо, так как важно время отклика, которое страдает от долгих запросов. А для пакетной обработки подход другой. Тут важна пропускная способность, а время отклика мало кого волнует.


Проблема — управляемое чтение больших массивов данных. Не в смысле количества байт, а в смысле числа строк. И мне показалось изначально разумным, что все сразу мы не получим и запрос будет разбит на подзапросы. Именно из-за требования больших таймаутов для исполнения большого запроса. Потому что практика показывает, что большой таймаут несет проблемы с реакцией оператора (не только в GUI), трудностями в отмене операции, трудностями в реагировании на сбои (понять, что отвалился сервер желательно как можно раньше, а у нас таймаут — час), трудностями с блокировкой ресурсов БД и отъеданием ресурсов сервера БД. Пейджинг — один из вариантов решения, но он больше на Grid ориентирован. Курсоры, как учат нас книги и интернет — вселенское тормозное зло. Что применять?

W>>>1. Обрабатывать на сервере (с помощью SQL или ХП).

N_P>>А как? Что по этому поводу почитать и где посмотреть пример?
W>Зависит от задачи и алгоритма. Если конечным результатом обработки миллиона строк является тысяча строк или сотня, то лучше сделать это на сервере, поближе к исходным данным, чтобы не тратить время на перекачку их по сети. Конечная выборка получится уже небольшая.

Ну, это как-бы понятно

W>Почитать — документацию по СУБД, там и примеры есть. Ну и на книжку вон ссылку уже кинули.


В документации про пейджинг точно нет. И, судя по тому, что ссылка была даже без указания главы в книге — это просто посыл на "RTFM".

W>>>2. Обрабатывать на клиенте, не помещая все в память.

N_P>>В память вполне можно получить полный ID записей.
W>Не понял?

Обычно нужен не вообще запрос, а выборка из таблицы с условиями. В этих случаях можно получить все ключи записей в память, а потом читать данные пачками. Случай частный, но частый.
Re: Чтение больших выборок данных частями
От: IB Австрия http://rsdn.ru
Дата: 23.03.16 13:59
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>Как принято решать такие вопросы ?

Принято таких проблем избегать. С практической точки зрения нет никакого смысла выгружать миллионы записей пользователю, он их все равно просмотреть не сможет.
Чтобы записей было не миллионы, а обозримое количество, придумали фильтры с уточняющими критериями для выборки.
В крайнем случае — постраничная выдача данных.

Если же речь не о пользователе, то тут другой разговор — для перегона данных из одного хранилища в другое есть масса нарошных способов.

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

Это примитивный способ организации постраничной выборки. В любой СУБД есть набор способов для правильной реализации такой конструкции. ключевое слово для поиска — "paging"
Мы уже победили, просто это еще не так заметно...
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...
Пока на собственное сообщение не было ответов, его можно удалить.