Queryable.OrderBy对SQL Server数据库不稳定吗?

时间:2018-04-19 18:07:54

标签: c# entity-framework linq linq-to-sql iqueryable

对于LINQ to Objects,

OrderBy是稳定的,但Queryable.OrderBy上的MSDN没有提及它是否稳定。

我想这取决于提供者的实现。它对SQL Server不稳定吗?因为它看起来如此。我快速查看了Queryable source code,但从那里开始并不明显。

我需要在其他操作之前订购一个集合,我想使用IQueryable而不是IEnumerable来提高性能。

// All the timestamps are the same and I am getting inconsistent 
// results by running it multiple times, first few pages return the same results
var result = data.OrderBy(i => i.TimeStamp).Skip(start).Take(length);

但如果我使用

var result = data.ToList().OrderBy(i => i.TimeStamp).Skip(start).Take(length);

它运行得很好,但是我从LINQ到SQL失去了性能提升。似乎Queryable OrderBy / Skip / Take的组合会产生不一致的结果。

生成的SQL代码对我来说似乎很好:

SELECT 
...
FROM [dbo].[Table] AS [Extent1]
ORDER BY [Extent1].[TimeStamp] ASC
OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY 

2 个答案:

答案 0 :(得分:2)

在Linq-to-Entities中LINQ查询被转换为SQL查询,因此OrderBy的Linq-to-Objects实现并不重要。您应该查看ORDER BY的数据库实现。如果您使用的是MS SQL,则可以在文档中找到:

  

要使用OFFSET和FETCH在查询请求之间获得稳定的结果,必须满足以下条件:   (...)

     
      
  1. ORDER BY子句包含保证唯一的列或列组合。
  2.   

因此,相同值的ORDER BY不保证相同的顺序,因此限制它可以提供不同的结果集。要解决此问题,您只需按一些具有唯一值的其他列进行排序即可。 ID。所以基本上你会有:

{{1}}

答案 1 :(得分:0)

我认为"稳定",你的意思是一致的。如果在SQL查询中没有ORDER BY,则每次运行查询时都无法保证数据的顺序。它将以任何对服务器最有效的顺序返回所有数据。添加ORDER BY时,它将对该数据进行排序。由于您要对所有排序值相同的数据进行排序,因此不会对任何行进行重新排序,因此排序的数据按照您不希望的顺序排列。如果您需要特定订单,则需要添加辅助排序列,例如ID。

最好不要假设从服务器返回的数据顺序,除非您明确定义该顺序是什么。