EXTREMELY Poor LINQ Query Performance When Using Skip/Take for Paging

送分小仙女□ 提交于 2019-12-04 11:54:13

Have you looked at the SQL that get generated for this query?

As far as I know Skip() Take() eventually results in a generated statement that uses a function called Row_Number(). This function is executed across the entire record set in the fashion shown below - To insert the row number as the first generated column in the result before taking values between the start and end values you desire, typically making it very very slow, on large record sets..

SELECT ...
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY [t0].[...]) AS [ROW_NUMBER], ... ,
    FROM [table] AS [t0]
    ) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1
ORDER BY [t1].[ROW_NUMBER]

If you can use an indexed numeric column and arrange it so that you read >= start_value AND <= end-value yourself, then move those values up by your paging amount it will use the index and return results in in milliseconds.

I have well indexed databases with 100's millions of records and Skip().Take() can take up to 30 minutes to obtain 25 records. Where are the direct read takes around 20-40ms.

It would mean you would have to think about the way you code to achieve paging, and may not be practicable to implement in your case.

My guess it's not due to linq, try to order by indexed column first and then do skip. In you first case, when you do just take, it doesn't go through rest of records and just picks top result, with skip it needs to sort them all to figure out order and then does skip based on it.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!