我正在运行这个查询:
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 是标识列 ...
有什么建议吗?
最佳答案
您一开始就在“SOMETABLE”上调用 ToList
。这是将包含所有行和所有列的整个数据库表拉入内存,然后通过 Linq-to-objects 对该内存中的数据结构执行所有后续操作。
您不仅会因为在网络上传输的信息比您需要的多(速度很慢)而遭受损失,而且 C# 执行这些操作的效率几乎无法与数据库相提并论。这部分是因为它失去了对任何索引、任何数据库缓存、任何缓存的编译查询的访问,它在处理开始时那么大的数据集时效率不高,以及查询本身的任何更高级别的优化(数据库倾向于做很多)。
接下来,您在 GroupBy
子句中有一个查询 from f in db.A_LAGE_TABLE where [...]
对 中的每一行执行顺序。如果在可能优化的数据库级别评估整个查询,即使不是,您也不会通过网络为每条记录传递信息(这非常慢)。
关于c# - LINQ 查询耗时太长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13822646/