2

执行 LINQ 语句时,要连接的列的位置对性能有影响吗?

例如,以下哪个查询运行最快,为什么?

一种)

 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
                        };

二)

   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());

似乎连接列的顺序可能会影响执行速度 - 或者正如所指出的,我的数据库可能效率低下:)

无论如何,我想将发现发布给任何觉得这很有趣的人。

4

1 回答 1

1

在 SQL 中,连接和列的顺序通常无关紧要:如果你有一个好的 SQL 优化器,并且你的数据库有很好的统计数据,那么数据库引擎会重组你的查询以获得最佳性能。

一般来说,对于 LINQ 来说并非如此:与 SQL 不同,语句不会重新排序以执行,而是按照它们输入的相同顺序懒惰地执行。如果您正在获取空间分离的数据,或者选择了错误的合并顺序,您的执行速度将会受到影响。

好消息是你应该是安全的。对于 LINQ to SQL 或 LINQ to Entities,虽然生成的 SQL(通常)与您键入的顺序大致相同,但您仍然会使用 SQL 数据库的优化引擎。在这种情况下,连接和列名的顺序通常无关紧要。

与往常一样,糟糕的统计数据或糟糕的数据库优化器仍然会咬你一口。在这种情况下,最好不要在 StackOverflow 上询问,而是通过拆分 SQL Profiler 来检查实际使用了哪些查询计划。

于 2012-10-04T14:57:47.767 回答