3

我正在运行这个查询:

List<RerocdByGeo>  reports = (from p in db.SOMETABLE.ToList()
       where (p.colID == prog && p.status != "some_string" && p.col_date < enddate && p.col_date > startdate)
       group p by new {
           country = (
           (p.some_integer_that_represents_an_id <= -0) ? "unknown" : (from f in db.A_LAGE_TABLE where (f.ID ==  p.some_integer_that_represents_and_id) select f.COUNTRIES_TABLE.COU_Name).FirstOrDefault()),
           p.status }
           into g
    select new TransRerocdByGeo
       {
           ColA = g.Sum(x => x.ColA),
           ColB = g.Sum(x => x.ColB),
           Percentage = (g.Sum(x => x.ColA) != null && g.Sum(x => x.ColA) != 0) ? (g.Sum(x => x.ColB) / g.Sum(x => x.ColA)) * 100 : 0,
           Status = g.Key.status,
           Country = g.Key.country
       }).ToList();

sql 中针对同一数据库的类似查询将运行几秒钟,而在好的情况下,这个查询大约需要 30-60 秒...

表 SOMETABLE 包含大约 10-60 K 行,此处称为 A_LARGE_TABLE 的表包含大约 10-20 行

coulmn some_inteher_that_reoresents_an_id 是大表上的 id,但也可以是 0 或 -1,并且需要获取“未知”值,所以我无法建立关系(或者我可以吗?如果可以,请解释)

COUNTRIES_TABLE 包含 100-200 行。

coulID 和 ID 是身份列...

有什么建议么 ?

4

2 回答 2

16

ToList在一开始就在调用“SOMETABLE”。这是将包含所有行和所有列的整个数据库表拉入内存,然后通过 Linq-to-objects 对该内存数据结构执行所有后续操作。

您不仅会遭受通过网络传输比您需要的更多信息的惩罚(这很慢),而且 C# 无法像数据库一样高效地执行操作。这部分是因为它失去了对任何索引、任何数据库缓存、任何缓存的编译查询的访问权限,它在处理一开始就很大的数据集以及查询本身的任何更高级别的优化方面效率不高(数据库往往会这样做)很多)。

接下来,您的GroupBy子句中有一个查询,该查询针对序列中的每一行from f in db.A_LAGE_TABLE where [...]执行。如果在可能会优化的数据库级别评估整个查询,即使不是,您也不会通过网络为每条记录传递信息(这很慢) 。

于 2012-12-11T15:14:35.590 回答
8
from p in db.SOMETABLE.ToList()

这基本上是说“从 SOMETABLE 获取每条记录并将其放入一个List”中,根本没有过滤。这可能是你的问题。

于 2012-12-11T15:15:07.443 回答