当没有使用ORDER BY时,SQL Server是否随机排序结果?为什么?

时间:2014-11-08 01:58:11

标签: sql-server

我在SSMS中有一个查询,它给了我相同的行数但每次按F5键时的顺序不同。这篇文章描述了一个类似的问题:

Query returns a different result every time it is run

给出的响应是包含一个ORDER BY子句,因为正如该帖子中的响应所解释的那样,如果不给它一个,SQL Server会猜测顺序。

好的,确实解决了这个问题,但我对SQL Server正在做的事情感到困惑。表具有物理顺序,无论它们是堆还是具有聚簇索引。每次执行查询时,每个表的物理顺序都不会改变,这也不会改变。我们每次都应该看到相同的结果!它做了什么,在他们的物理订单中访问表,然后,它不是通过不变的物理订单显示结果,而是随机排序结果?为什么?我错过了什么?谢谢!

3 个答案:

答案 0 :(得分:2)

简单 - 如果您想按特定顺序记录,请按特定顺序询问。

如果您没有要求订单,则无法猜测。 SQL只是做了方便。

答案 1 :(得分:1)

一种可以获得不同排序的方法是并行性在起作用。想象一下简单的选择(即select * from yourTable)。假设优化器为该查询生成并行计划,并行度为4.每个线程将处理(大致)表的1/4。但是,如果你的服务器不是服务器上的唯一工作负载,那么每个线程都将处于运行状态和可运行状态之间(仅仅根据SQLOS调度线程的性质,即使你的 是服务器上唯一的工作负载,但如果必须共享,则会加剧。)由于您无法控制在任何给定时间运行的线程,并且因为每个线程一旦检索到它们就会返回其结果(因为它不必进行任何连接,聚合等),顺序行返回的行是不确定的。

要测试此理论,请尝试使用maxdop = 1查询提示强制执行序列计划。

答案 2 :(得分:0)

SQL服务器为每个表使用一组统计信息来协助速度和连接等...如果统计信息为最新路由提供了模糊选择,则SQL的选择可以是任意的 - 并且可能需要稍微不同的索引才能实现...因此输出顺序不同。物理顺序只是预测顺序的一个小因素。任何索引,连接,where子句都可以影响顺序,因为如果相应的索引尚不存在,SQL也将创建并使用自己的临时索引来帮助满足查询。尝试重新计算所涉及的每个表的统计数据,然后查看是否有任何变化或一致性。

您可能不是每次都获得随机顺序,而是在少数类似加权的路径之间进行任意选择以从查询中获得相同的结果。