Производительность LINQ to SQL с запросами «SELECT TOP {x}» - PullRequest
2 голосов
/ 11 января 2010

При поиске того, как выполнить эквивалент SELECT TOP 5 с LINQ-to-SQL, все ответы, которые я видел, предлагают использовать .Take (), например так:

var myObject = (
from myObjects in repository.GetAllMyObjects()
select myObject)
.Take(10);

Я пока не понимаю большей части того, как LINQ работает за кулисами, но, насколько я понимаю, языки, подобные С, решили эту проблему, сначала назначив временный массив, содержащий ВСЕ записи, а затем скопировав первые 10 элементов в массив к вар. Это не проблема, если вы работаете с небольшим набором данных или без каких-либо ограничений производительности, но мне кажется, что это неэффективно, если вы выбираете, например, 5 последних записей журнала из таблицы, которая может содержать миллионы записей.

Мое понимание того, как это работает неправильно? Если так, может кто-нибудь объяснить, что на самом деле происходит? В противном случае, какой (если таковой имеется) лучший (то есть более эффективный) способ выбора только x записей через LINQ-to-SQL?

[править]

У меня есть гипотетический класс myObject, отправляющий выходные данные LINQ-to-SQL на выходные данные отладки согласно предложению в принятом ответе. Я закончил тем, что использовал DebuggerWriter отсюда: http://www.u2u.info/Blogs/Kris/Lists/Posts/Post.aspx?ID=11

Ответы [ 3 ]

3 голосов
/ 11 января 2010

Ваше предположение неверно. С Linq to SQL он оценивается как Expression<Func<...>>, который можно оценить и сгенерировать правильный SQL. Вам не нужно беспокоиться об этом, загружая все записи.

Также см. Следующий вопрос. Вы можете присоединить поток к вашему DataContext и посмотреть сгенерированный SQL. Как получить запрос TSQL из LINQ DataContext.SubmitChanges ()

1 голос
/ 11 января 2010

Я только что прошел эту последнюю неделю! Я открыл профилировщик SQL в своей базе данных dev и прошел по коду. Было очень интересно увидеть сгенерированный SQL для различных запросов. Я рекомендую вам сделать то же самое. Возможно, это не точный ответ на ваш вопрос, но было определенно поучительно, когда вы видите, как ваши различные компоненты генерируют совершенно разные операторы SQL в зависимости от содержимого вызова.

Я полагаю, что "отложенное разрешение запроса" или что-то (?) Чтение в MSDN также будет полезным.

1 голос
/ 11 января 2010

LINQ использует отложенное выполнение и, для LINQ-to-SQL, деревья выражений.

Ни один запрос не будет выполнен, пока вы не перечислите результат вызова Take, поэтому вам не о чем беспокоиться.

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