【发布时间】:2012-10-09 14:25:20
【问题描述】:
我有一些看起来像这样的代码,使用 .NET 3.5(客户要求):
void Process (ActionState state)
{
var orderItemQuery = from OrderItem item in order.OrderItems
orderby item.OrderLineNumber ascending
select item;
foreach (OrderItem item in orderItemQuery)
{
ActionData actionData;
switch (state)
{
case ActionState.Prepare:
actionData = (
from ActionData ad in db.ActionDataTable
where ad.ObjectId == item.ProductId
select ad
).First();
case ActionState.QualityCheck:
actionData = (
from ActionData ad in db.ActionDataTable
where ad.ObjectId == item.OrderItemId
select ad
).First();
default:
throw new InvalidOperationException();
}
// ...
}
}
本质上,第一个查询的结果是迭代的,并且基于当前的ActionState,使用特定的外键从数据库中获取ActionData 记录。实际上,这里和那里有更多的嵌套和一些检查,但本质上是相同的。
这最初对测试数据库非常有效,但一位客户刚刚向我发送了一份他们的实时数据的副本,而且速度非常慢。运行整个批次大约需要 15 分钟,包括一些其他处理。通过性能测试器运行代码后,我发现整个过程中最慢的部分是每个案例的.First() 调用。
如果这是纯 SQL,我会根据 state 的值在循环外编译一个存储过程,然后使用它。既然我做不到,那还有什么办法呢?如何加快速度?
【问题讨论】:
-
请注意,实际上并不是 .First() 是性能问题,而是 Linq 语句在 .First() 执行之前不会执行。所以实际的性能影响可能在 Linq 语句本身。
-
Linq 语句在 foreach 上执行。所以它向 sql server 发送了 100500 个请求(每个订单一个请求)。
标签: c# performance linq linq-to-sql