Обработка больших запросов на выборку SQL / Чтение данных sql порциями - PullRequest
9 голосов
/ 20 апреля 2011

Я использую .Net 4.0 и SQL Server 2008 R2.

Я выполняю большой запрос выбора SQL, который возвращает миллионы результатов и занимает много времени для полного выполнения.

Кто-нибудь знает, как я могу прочитать только некоторые результаты, возвращенные запросом, не дожидаясь завершения всего запроса?

Другими словами, я хочу прочитать первые по 10000 фрагментов записей, пока запрос еще выполняется и получает следующие результаты.

Ответы [ 3 ]

12 голосов
/ 20 апреля 2011

Частично это зависит от того, является ли сам запрос потоковым или выполняет ли он много работы во временных таблицах , тогда (наконец-то) начинает возвращать данные.Вы не можете многое сделать во втором сценарии, кроме как переписать запрос;однако в первом случае блок итератора обычно помогает, например

public IEnumerable<Foo> GetData() {
     // not shown; building command etc
     using(var reader = cmd.ExecuteReader()) {
         while(reader.Read()) {
             Foo foo = // not shown; materialize Foo from reader
             yield return foo;
         }
     }
}

Теперь это потоковый итератор - вы можете foreach поверх него и он будет извлекать записи в реальном времени из входящих данных TDS без буферизациисначала все данные.

Если вы (возможно, мудро) не хотите писать свой собственный код материализации, есть инструменты, которые сделают это за вас - например, LINQ-to-SQL ExecuteQuery<T>(tsql, args) сделаетсделать вышеописанное безболезненно.

2 голосов
/ 20 апреля 2011

Вам нужно использовать подкачку данных.

SQL Server имеет предложение TOP ( SQL TOP 10 a, b, c из d ) и МЕЖДУ :

SELECT TOP 10000 a,b,c from d BETWEEN X and Y

Имея это, я полагаю, вы сможете получить N строк, выполнить некоторую частичную обработку, затем загрузить следующее N строк и т. Д.

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

0 голосов
/ 20 апреля 2011

, если вам действительно нужно обработать миллионы записей. Почему вы не загружаете 10 000 в каждом раунде, а затем загружаете следующие 10 000?Если не рассматривать возможность использования СУБД для фильтрации данных перед их загрузкой, так как производительность в базе данных намного выше, чем в вашей логике.

Или следуйте ленивой концепции загрузки и загружайте только идентификаторы, в которые вы загружаете фактические данные только тогда, когда они вам нужны.

...