我正在运行此查询:
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是标识列......
有什么建议吗?
答案 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
”,而不进行过滤。这可能是你的问题。