6

我有一个包含 200,000 条记录的表格,我只使用前 10 条记录,.Take()但获取数据大约需要 10 秒。

我的问题是:该.Take()方法是否从数据库中获取所有数据并在客户端过滤前 10 名?

这是我的代码:

mylist = (from mytable in db.spdata().OrderByDescending(f => f.Weight)
                                    group feed by mytable.id into g
                                    select g.FirstOrDefault()).Take(10).ToList();

spdata()是一个从存储过程导入的函数。

谢谢

4

4 回答 4

9

存储过程可能会向客户端返回大量数据,这非常慢。您不能远程查询到存储过程。使用视图或表值函数可以做到这一点。

无法在查询中使用存储过程。您只能自己执行它。

您的意图可能是Take(10)在服务器上执行。为此,您需要切换到内联查询、视图或 TVF。

于 2012-12-18T13:42:13.320 回答
7

扩展方法Take不会从数据库获取所有结果。这不是如何Take工作的。

但是,您的db.spdata()调用可能会获取所有行。

于 2012-12-18T13:41:54.983 回答
1

我不是 100% 确定,但我记得当您使用 EF DataContext 调用 SP 时,您会得到一个 IEnumerable 结果...

有几个是为了优化性能:

  • 将搜索条件 s 作为 SP 参数传递,并在存储过程中进行过滤。

或者,如果您在 SP 中有一个非常简单的查询,您没有声明任何变量并且您只是加入一些表,那么:

  • 创建一个索引视图,在其中指定您需要的查询并在其上调用 Take 方法。
    这会给你什么?您可以映射到创建的视图,EF 现在将返回 IQueryable 结果而不是 IEnumerable。这将优化 sql 命令,而不是接收所有数据,然后获取您需要的 10 个元素,将形成一个仅检索 10 个元素的 sql 命令。

我还建议您了解 IEnumerable 与 IQueryable 之间的区别。

于 2012-12-18T13:50:03.920 回答
0

确实如此,因为您在分组之前对数据进行了排序,而这在 SQL 中是不可能的。

您应该使用聚合从每个组中获取最高权重,然后对权重进行排序以获得最大的十个:

mylist = (
  from mytable in db.spdata()
  group feed by mytable.id into g
  select g.Max(f => f.Weight)
).OrderByDescending(w => w).Take(10).ToList();
于 2012-12-18T14:05:09.133 回答