执行LINQ语句时,列的连接是否与性能有关?
例如,以下哪个查询运行速度最快,为什么?
A)
var query = from o in entities.orders
join i in entities.order_items
on o.OrderId equals i.OrderId
where o.AddedSalesOrder == 0
select new
{
i.ShippingFirstName,
i.ShippingLastName,
i.Sku,
i.Quantity,
i.ItemPrice,
o.TotalShippingCost,
o.OrderId,
o.OrderCreateDate
};
B)
var query = from o in entities.orders
join i in entities.order_items
on o.OrderId equals i.OrderId
where o.AddedSalesOrder == 0
select new
{
o.TotalShippingCost,
o.OrderId,
o.OrderCreateDate,
i.ShippingFirstName,
i.ShippingLastName,
i.Sku,
i.Quantity,
i.ItemPrice
};
C)
var query = from o in entities.orders
join i in entities.order_items
on o.OrderId equals i.OrderId
where o.AddedSalesOrder == 0
select new
{
o.OrderCreateDate,
i.ShippingFirstName,
i.ShippingLastName,
o.TotalShippingCost,
o.OrderId,
i.Sku,
i.Quantity,
i.ItemPrice
};
我期望查询B最有效,因为为连接放置了列,导致生成更清晰的SQL代码,但我可能错了。
如果重要,则查询将在SQL Server 2008r2数据库上运行。
- 编辑 -
为了它的价值,我通过C#运行了一个快速(并且肯定是非绝对的)基准测试,以了解性能在每个场景中的表现。我的发现如下:
a) 297.61 millisecond avg over 100000 iterations
b) 245.90 millisecond avg over 100000 iterations
c) 304.16 millisecond avg over 100000 iterations
我用来测试的代码如下:
var sw = new Stopwatch();
List<long> totalTime = new List<long>();
for (int u = 0; u < 100000; u++)
{
sw.Start();
var entities = new Entities();
var query = from o in entities.orders
join i in entities.order_items
on o.OrderId equals i.OrderId
where o.AddedSalesOrder == 1
select new
{
i.ShippingFirstName,
i.ShippingLastName,
i.Sku,
i.Quantity,
i.ItemPrice,
o.TotalShippingCost,
o.OrderId,
o.OrderCreateDate
};
var qc = query.Count();
sw.Stop();
totalTime.Add(sw.ElapsedMilliseconds);
sw.Reset();
}
Console.WriteLine("Average time in Milliseconds: {0}", totalTime.Average());
看来,连接列的排序可能会影响执行速度 - 或者正如所指出的那样,我的数据库可能效率低下:)。
无论如何,我想把结果发布给任何发现这个有趣的人。
答案 0 :(得分:1)
在SQL中,连接和列通常的顺序无关紧要:如果您有一个好的SQL优化器,并且您的数据库有很好的统计信息,那么数据库引擎将重构您的查询最高性能。
通常,对于LINQ来说不是真的:与SQL不同,语句不会被重新排序以执行,而是按照它们键入的相同顺序延迟执行。如果您正在抓取空间分离的数据,或选择错误的合并订单,您的执行速度将受到影响。
好消息是你应该安全。对于LINQ to SQL或LINQ to Entities,虽然生成的SQL(通常)与您键入的顺序大致相同,但您仍然会访问SQL数据库的优化引擎。在这种情况下,连接和列名的顺序通常无关紧要。
与往常一样,糟糕的统计数据或糟糕的数据库优化程序仍然可以咬你。在这种情况下,不要在StackOverflow上询问,最好的办法是通过分解SQL事件探查器来检查实际使用的查询计划。