LINQ Skip () Проблема - PullRequest
       1

LINQ Skip () Проблема

5 голосов
/ 10 марта 2011

Оператор C # ниже блокирует процесс и не может получить данные, если itemToSkip больше 0.

 int itemToSkip = 100;
 int itemToTake = 1000;

 var itemList = db.MYTABLEs.Skip(itemToSkip).Take(itemToTake).ToList();

Как я могу это исправить? в чем проблема?

Ответы [ 4 ]

8 голосов
/ 10 марта 2011

Не уверен, какой провайдер предоставляет db.MYTABLE. На самом деле невозможно ответить на ваш вопрос, если мы не знаем, как ведет себя db.MYTABLE.

В обычном LINQ пропуск не просто пропустить; он должен перебирать количество данных, чтобы пропустить. Следовательно, для вашей таблицы данных 14 ГБ она будет проходить итерацию по первому количеству пропущенных записей. Если эта итерация медленная, вы не экономите время и ресурсы, пропуская.

Для некоторых провайдеров, например В источнике SQL пропуск может быть реализован с помощью курсоров, что опять может быть медленным. Если это SQL Server, его можно оптимизировать с помощью ключевого слова, которое может быть быстрее.

Если это LINQ-to-SQL, он переводит запрос в SQL с помощью предложения «НЕ СУЩЕСТВУЕТ», которое будет чрезвычайно медленным, потому что оно должно пройти через все таблица, если предложение NOT EXISTS не попадает в индекс. Смотрите следующее ( ссылка ):

LINQ to SQL переводит Пропустить используя подзапрос с SQL NOT СУЩЕСТВУЕТ пункт. Этот перевод имеет следующие ограничения:

  • Аргумент должен быть набором. Мультисеты не поддерживаются, даже если заказаны.

  • Сгенерированный запрос может быть намного более сложным, чем запрос, сгенерированный для базового запроса, к которому применяется Skip. Эта сложность может привести к снижению производительности или даже к истечению времени ожидания.

Другими словами, в документах написано "не делай этого".

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

Наихудший случай будет, если вы работаете с провайдером, который автоматически сортирует весь набор данных, если вы используете Skip / Take. Если у вас есть 14 ГБ данных, то сортировка будет очень медленной.

Вам нужно еще немного поэкспериментировать, чтобы проверить, не зависает ли ваша программа при пропуске, или просто включить весь процессор, пытаясь выполнить итерацию.

Если вы только пытаетесь разделить ваши данные на управляемые порции, вам, вероятно, не следует использовать skip / take, который запрашивает источник данных каждый раз.

3 голосов
/ 10 марта 2011

Пропустить обычно настаивает на наличии явного порядка сортировки. Попробуйте

var itemList = db.MYTABLEs.OrderBy(r => r.Id).Skip(itemToSkip)

или аналогичный.

0 голосов
/ 10 марта 2011

с такой большой таблицей возможно, что для ее возврата требуется много времени, и это занимает слишком много времени из-за отсутствия индексов, вам нужно выполнить некоторое профилирование, чтобы увидеть базовый запрос, вы не можете просто диагностировать проблемуглядя на код LINQ

0 голосов
/ 10 марта 2011

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

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