我已经写了一个asp.net网站,用于创建充满指定项目的报告(到Excel中)。我通过EF从SQL DB获取这些项目。查询效果很好,需要大约2000个项目大约1ms。
var itemsToQuery = (from i in context.item
where ......
.....
.....
orderby .......
select new
{
fields.....
});
现在对我来说很棘手。 Foreach项目我必须从数据库中查询额外数据(没有机会通过第一个查询获取这些数据)。我只使用一个数据库连接来保证安全时间(对于主查询和方法中的所有其他查询)。我认为我的性能问题从这里开始。我有2000个项目,以下循环如下所示:
foreach(var item in itemsToQuery)
{
another query;
another query;
another query;
etc.....
// at the end it looks like
datatable.add(item.name, item.number, item.stuff ......);
}
所以我为这2000个项目中的每一个做了另外8个查询。这个foreach大约需要5分钟(取决于项目数)。之后我需要这个DataTable来填充我的Excel表格。这样做很好,并且快速"。
你能否给我一些专家建议如何使这个循环,查询或填充DataTable更高效?
我考虑过使用多任务处理并创建一个站点,您可以在其中查看Excel的状态(通过ajax调用),一旦完成,您就可以下载它。现在我只是阻止这个网站的用户界面,用户必须坐在屏幕前,直到完成没有任何信息,他需要等待多长时间。带有gif和js的屏幕示例,用于运行时钟:
一件重要的事情 - 我不能在数据库中创建视图或存储过程,因为我不允许这样做。我必须在后面的代码中执行每个查询等。
我知道该程序是业余的,但这就是我必须紧急改变的原因。
[编辑]
以下是我所讨论的示例查询!仅供参考 - 我没有写过每个查询。其中一些(如owner
或monthlyWorkTime
)来自外部资源。
String changeDate = CalcÄnderungsDat(context
.ticket_history
.FirstOrDefault(x => x.history_type_id == 25 && x.ticket_id == item.ticketID).change_time.ToString());
String finishdate = CalcFinishDat((from tih in context.ticket_history
where (tih.name == "Reset of unlock time." && tih.ticket_id == item.ticketID)
|| (tih.state_id == 2 && tih.history_type_id == 1 && tih.ticket_id == item.ticketID)
select tih.change_time).Max().ToString());
try
{
string owner= (from a in context.article
where
item.ticketID == a.ticket_id &&
a.id ==
(from art in context.article
where art.a_subject.Contains("esitzer")
&& art.ticket.id == item.ticketID
&& art.ticket_id == art.ticket.id
select new { art.id }).Max(p => p.id)
select new { a.a_from }).FirstOrDefault().a_from;
}
catch (Exception)
{
string owner = (from a in context.article
where a.ticket.id == item.ticketID && a.ticket_id == a.ticket.id &&
a.id ==
(from art in context.article
where art.ticket.id == item.ticketID
&& art.ticket_id == art.ticket.id
select new { art.id }).Min(p => p.id)
select new { a.a_from }).FirstOrDefault().a_from;
}
decimal? monatszeit = (from ta in context.time_accounting
where
ta.change_time >= startdat &&
ta.change_time <= enddat &&
ta.ticket_id == item.ticketID
group new { ta } by new
{
ta.ticket_id,
ta.ticket.id,
ta.ticket.tn
} into g
select new
{
Zeiteinheit = (Decimal?)g.Sum(p => p.ta.time_unit),
}).SingleOrDefault().Zeiteinheit;
等等。总体而言,有7个查询和1个外部方法用于计算主查询中每个项目的特殊日期(此方法不应该是问题)。我如何将它们放在一个完整的查询中?它会提高我的表现吗?
[编辑 - 另一个尝试!]
您对此流程图有什么看法?
那肯定会提升性能!对于这么小的项目来说,这听起来有多大工作吗?
答案 0 :(得分:0)
您可以考虑为已检索的数据创建缓存解决方案。因此查询结果将存储在内存中,并且每次都不会检索它,因此性能会大大提高。
您必须考虑刷新缓存的频率。其他选项是检查是否出现了一些新数据,并进行仅检索最新数据的查询。