我的代码中有两个查询:
var query1 = (
from c in db.HugeTableData
where c.price >= 1000
group c by new { c.year, c.month, c.day } into cgroup
select new { Count = cgroup.Count(), cgroup.Key })
.OrderByDescending(x => x.Key.year).ThenByDescending(y => y.Key.month)
.ThenByDescending(z => z.Key.day).Take(50);
//Some other code
var query2 = (
from c in db.HugeTableData
where c.price >= 1000 && c.check == true
group c by new { c.year, c.month, c.day } into cgroup
select new { Count = cgroup.Count(), cgroup.Key })
.OrderByDescending(x => x.Key.year).ThenByDescending(y => y.Key.month)
.ThenByDescending(z => z.Key.day).Take(50);
这两个查询是从具有大量数据的表中检索限定记录,并且您看到它们之间的唯一区别是&& c.check == true
部分,但我不是在寻找如何重构它。不幸的是,这段代码运行速度很慢,现在我的问题是:性能是否低,因为两次往返DataBase?而且如果我有大量数据,那么存储过程是一个不错的选择吗?
编辑:使用这些查询的代码如下:
foreach (var item in query1)
{
DateTime dt = Convert.ToDateTime(item.Key.year + "-" + item.Key.month + "-" + item.Key.day);
string temp = MyConvertToStringMethod(dt);
if (firstDictionary.ContainsKey(temp))
firstDictionary[temp] = item.Count;
}
另外foreach
与query2
相似,以填充secondDictionary
。
答案 0 :(得分:1)
您只检索前50条记录。如果记录的总数很小并且可以将完整的结果保存在内存中,那么您可以通过检查分组来避免两次往返数据库,即
var list = (
from c in db.HugeTableData
where c.price >= 1000
group c by new { c.year, c.month, c.day , c.check } into cgroup
select new {
Count = cgroup.Count(),
cgroup.Key.year ,
cgroup.Key.month,
cgroup.Key.day
}).ToList();
然后你可以执行linq-to-objects查询
var query1 = (
from c in list
group c by new { c.year, c.month, c.day } into cgroup
select new { Count = cgroup.Sum(), cgroup.Key })
.OrderByDescending(x => x.Key.year).ThenByDescending(y => y.Key.month)
.ThenByDescending(z => z.Key.day).Take(50);
var query2 = (
from c in list where c.check == true
group c by new { c.year, c.month, c.day } into cgroup
select new { Count = cgroup.Sum(), cgroup.Key })
.OrderByDescending(x => x.Key.year).ThenByDescending(y => y.Key.month)
.ThenByDescending(z => z.Key.day).Take(50);
//请注意,您需要使用Count=cgroup.Sum()
答案 1 :(得分:0)
根据您的情况,您可以采取多种方法。最广泛适用的是创建一个实现此逻辑的视图,然后直接使用它。根据您的Dbms,您可以通过使用索引进一步加快此方法。 或者,如果结果处理速度很慢,您可以在枚举结果时使用c#yield关键字,以便在枚举数据时对其进行处理。