当要跳过的数字很大时,实体Framerowk Skip/Take非常慢

ber*_*ner 11 sql linq performance entity-framework

所以,代码非常简单:

var result = dbContext.Skip(x).Take(y).ToList();
Run Code Online (Sandbox Code Playgroud)

当x很大(~1.000.000)时,查询非常慢.y很小 - 10,20.

这个的SQL代码是:(来自sql profiler)

SELECT ...
FROM ...
ORDER BY ...
OFFSET x ROWS FETCH NEXT y ROWS ONLY
Run Code Online (Sandbox Code Playgroud)

问题是,是否有人知道如何加快这种分页?谢谢.

Ale*_*xei 7

我认为OFFSET..FETCH在浏览大数据的第一页时非常有用(这在大多数应用程序中经常发生)并且在从大数据查询高阶页面时有性能缺陷。

检查此文章了解有关性能和替代更多的细节OFFSET.. FETCH

在应用分页之前尝试对您的数据应用尽可能多的过滤器,以便针对较小的数据量运行分页。很难想象用户不想浏览 1M 行。


Cet*_*soz 6

你是对的,Skip().Take() 方法在 SQL 服务器上很慢。当我注意到我使用了另一种方法并且效果很好时。我没有使用 Linq Skip().Take() - 它编写你展示的代码 - ,我明确地将 SQL 编写为:

select top NTake ... from ... order by ... where orderedByValue > lastRetrievedValue 
Run Code Online (Sandbox Code Playgroud)

这个工作得很快(考虑到我有按列排序的索引)。


Kin*_*rUY 5

与其他方式相比,在数据库中导航一百万条记录总是很慢,数据库必须“跳过”一百万条记录,它通过在内存中创建结果然后丢弃前一百万行来做到这一点。

您是否考虑过非 sql 替代方案(solr、lucene 等),至少先获取行的 id,然后在 () 查询中使用 where id?

或者,您可以拥有一个主表的搜索表(预制表),其中仅包含最少的数据和 ID,因此您可以跳过该表并获取 ID 并使用这些查询大表。