LINQ查询耗时太长

时间:2012-12-11 15:10:45

标签: c# sql linq entity-framework

我正在运行此查询:

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是标识列......

有什么建议吗?

2 个答案:

答案 0 :(得分:15)

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

您不仅要承受通过网络传输更多信息的惩罚(这很慢),而且C#无法像数据库那样高效地执行操作。这部分是因为它无法访问任何索引,任何数据库缓存,任何缓存的编译查询,它在处理大型数据集时效率不高,并且查询本身的任何更高级别的优化(数据库倾向于很多)。

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

答案 1 :(得分:8)

from p in db.SOMETABLE.ToList()

这基本上是说“从SOMETABLE获取所有记录并将其放入List”,而不进行过滤。这可能是你的问题。