问题定义:我有一个包含数百万条目的数据库表。该表使用以下列定义:Date,Value和NumberOfEvents。我需要在几个时间间隔之间获取数据,并对每个间隔的所有返回记录应用函数(Sum,Average,Max,Min)。
当前解决方案
List<SingleSeries> series = new List<SingleSeries>();
//Iterate intervals
for (int i = 0; i < intervals.Count(); i++)
{
if (i == 0)
{
}
if (i + 1 < intervals.Count())
{
//Get database entries between interval
var validKpis = kpis.Where(x => x.Date >= intervals.ElementAt(i) && x.Date < intervals.ElementAt(i + 1));
//Apply calc operation (SUM; AVG; MAX;MIN)
var result= CalcOperations.Calculate(calcOperation, validKpis);
//Add result to results array
series.Add(new SingleSeries()
{
Value = result,
Name = DateOperations.ConvertToMilliseconds(intervals.ElementAt(i + 1)).ToString()
});
};
}
return series;
当前问题:目前此函数对数据库执行N个查询,其中N = intervals.Count()/ 2。我想它只做一个查询,但我不知道如何使用区间数组聚合每个区间的值,并对其应用计算操作。建议吗?
您需要构建单个查询,该查询将获取所有间隔的结果,然后循环显示间隔以将结果集拆分为每个特定间隔的结果集。
它的代码更多一些,但更有效地使用数据库请求。
这是一个粗略的片段,展示了上述内容 - 请注意,我没有对此进行测试 - 它只是为了让您具体了解如何使用单个查询来执行此操作。
List<SingleSeries> series = new List<SingleSeries>();
var kpiQuery = kpis;
//Iterate intervals and build a single query to retrieve all of them
for (int i = 0; i < intervals.Count(); i++)
{
if (i + 1 < intervals.Count())
{
// add each target interval sequentially - without running the query yet
kpiQuery = kpiQuery.Where(x => x.Date >= intervals.ElementAt(i) && x.Date < intervals.ElementAt(i + 1));
}
}
var validKpis = kpiQuery.ToList(); // now get all database results in a single transaction
//Iterate the intervals again, this time to split the combined results that are now in memory
for (int i = 0; i < intervals.Count(); i++)
{
if (i + 1 < intervals.Count())
{
//select only the results applicable to the current interval
var kpisInThisInterval = validKpis.Where(x =>
x.Date >= intervals.ElementAt(i) && x.Date < intervals.ElementAt(i + 1));
//Apply calc operation (SUM; AVG; MAX;MIN)
var result = CalcOperations.Calculate(calcOperation, kpisInThisInterval);
//Add result to results array
series.Add(new SingleSeries()
{
Value = result,
Name = DateOperations.ConvertToMilliseconds(intervals.ElementAt(i + 1)).ToString()
});
}
}
return series;