Chr*_*lis 5 sql t-sql sql-server oracle
我一遍又一遍地读到它,SQL的核心是无序模型.这意味着多次执行相同的SQL查询可以以不同的顺序返回结果集,除非包含"order by"子句.有人可以解释为什么SQL查询可以在运行查询的不同实例中以不同的顺序返回结果集吗?情况可能并非如此,但肯定是可能的.
从算法上讲,当没有"order by"子句时,查询计划在确定结果集的顺序时不起任何作用吗?我的意思是当有一些查询的查询计划时,算法如何不总是以相同的顺序返回数据?
注意:我没有质疑订单的使用,我问为什么没有保证,因为我正在试图理解由于无法保证所带来的挑战.
Mar*_*ith 16
一些SQL Server示例中完全相同的执行计划可以返回不同排序的结果
Martin Smith有一些很好的例子,但是证明SQL Server何时会改变所使用的计划的绝对死的简单方法(因此根据不同的计划,将使用没有ORDER BY的查询的顺序)是添加覆盖索引.举个简单的例子:
CREATE TABLE dbo.floob
(
blat INT PRIMARY KEY,
x VARCHAR(32)
);
INSERT dbo.floob VALUES(1,'zzz'),(2,'aaa'),(3,'mmm');
Run Code Online (Sandbox Code Playgroud)
这将按群集PK排序:
SELECT x FROM dbo.floob;
Run Code Online (Sandbox Code Playgroud)
结果:
x
----
zzz
aaa
mmm
Run Code Online (Sandbox Code Playgroud)
现在,让我们添加一个恰好涵盖上述查询的索引.
CREATE INDEX x ON dbo.floob(x);
Run Code Online (Sandbox Code Playgroud)
当我们再次运行它时,索引会重新编译上面的查询; 现在它按新索引排序,因为该索引为SQL Server提供了一种更有效的方式来返回结果以满足查询:
SELECT x FROM dbo.floob;
Run Code Online (Sandbox Code Playgroud)
结果:
x
----
aaa
mmm
zzz
Run Code Online (Sandbox Code Playgroud)
看看这些计划 - 既没有排序运算符,也没有任何其他排序输入 - 依赖于索引的固有顺序,他们正在扫描整个索引,因为它们必须(并且最便宜的SQL方式)服务器扫描索引是按顺序).(当然,即使在这些简单的情况下,马丁答案中的一些因素可能会影响不同的顺序;但在没有任何这些因素的情况下,情况也是如此.)
正如其他人所说,依赖订单的唯一方式是指定订单.请把它写在某个地方.无论有多少场景存在,这种信念可能会破裂; 甚至有一个这样的事实使得试图找到一些指导方针,因为你可以懒惰而不使用ORDER BY子句是徒劳的.只需始终使用它,或者为数据做好准备,并不总是以相同的顺序返回.
一些相关的想法: