Попытка дать вам краткий ответ на ваши сомнения, если вы выполняете методы skip(n).take(m)
в linq (с SQL 2005/2008 в качестве сервера базы данных), ваш запрос будет использовать оператор Select ROW_NUMBER() Over ...
, с каким-то образом прямой подкачкой страниц в движке SQL.
Приведу пример. У меня есть таблица базы данных с именем mtcity
, и я написал следующий запрос (также работает с linq для сущностей):
using (DataClasses1DataContext c = new DataClasses1DataContext())
{
var query = (from MtCity2 c1 in c.MtCity2s
select c1).Skip(3).Take(3);
//Doing something with the query.
}
Результирующий запрос будет:
SELECT [t1].[CodCity],
[t1].[CodCountry],
[t1].[CodRegion],
[t1].[Name],
[t1].[Code]
FROM (
SELECT ROW_NUMBER() OVER (
ORDER BY [t0].[CodCity],
[t0].[CodCountry],
[t0].[CodRegion],
[t0].[Name],
[t0].[Code]) AS [ROW_NUMBER],
[t0].[CodCity],
[t0].[CodCountry],
[t0].[CodRegion],
[t0].[Name],
[t0].[Code]
FROM [dbo].[MtCity] AS [t0]
) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1
ORDER BY [t1].[ROW_NUMBER]
Что такое оконный доступ к данным (довольно круто, кстати, потому что они будут возвращать данные с самого начала и будут обращаться к таблице, пока выполняются условия). Это будет очень похоже на:
With CityEntities As
(
Select ROW_NUMBER() Over (Order By CodCity) As Row,
CodCity //here is only accessed by the Index as CodCity is the primary
From dbo.mtcity
)
Select [t0].[CodCity],
[t0].[CodCountry],
[t0].[CodRegion],
[t0].[Name],
[t0].[Code]
From CityEntities c
Inner Join dbo.MtCity t0 on c.CodCity = t0.CodCity
Where c.Row Between @p0 + 1 AND @p0 + @p1
Order By c.Row Asc
За исключением того, что этот второй запрос будет выполнен быстрее, чем результат linq, поскольку он будет использовать исключительно индекс для создания окна доступа к данным; это означает, что если вам нужна некоторая фильтрация, фильтрация должна быть (или должна быть) в списке сущностей (где создается строка), а также должны быть созданы некоторые индексы для поддержания хорошей производительности.
Теперь, что лучше?
Если в вашей логике достаточно солидный рабочий процесс, реализация правильного способа SQL будет сложной. В этом случае LINQ будет решением.
Если вы можете понизить эту часть логики непосредственно до SQL (в хранимой процедуре), это будет еще лучше, потому что вы можете реализовать второй запрос, который я вам показал (с помощью индексов), и позволить SQL генерировать и хранить выполнение План запроса (повышение производительности).