SQL Server 2000 和 2012 之间的数据排序变化

SQL Server 2000 和 2012 之间的数据排序变化

我的公司最近将 .NET 1.1/SQL Server 2000 Web 应用程序迁移到了 SQL Server 2012。我们接到了一些与异常行为有关的支持电话 - 特别是没有 ORDER BY 子句的存储过程查询。

我知道依赖于这些类型的查询的顺序的功能是一种不好的做法 - 但是否有人知道是否有关于 SQL Server 版本之间默认顺序变化的官方 Microsoft 文档?

答案1

SQL Server 2012 不保证在 SQL 2012 中返回的行的顺序。2000 也是如此。(我找到的引用实际上是2005,但足够接近了。)

本质上,SQL Server 查询优化器保证查询树中的内部运算符将按特定顺序处理其输入。没有相应的保证说该运算符的输出将暗示查询树中的下一个运算符将按该顺序执行。重新排序规则可以并且将违反此假设(并且当它对您(开发人员)不方便时会这样做;)。请理解,当我们重新排序操作以找到更高效的计划时,我们可能会导致树中中间节点的排序行为发生变化。如果您在树中放置了一个假设特定中间排序的操作,它可能会中断。

基本上:到目前为止你都很幸运,但最终你还是幸运的。

本文Itzik Ben-Gan 撰写的文章可能会对你有所帮助。示例如下:

集合最重要的方面之一隐含在 Cantor 的定义中。他没有提到集合中元素的顺序,因为顺序并不重要。这是人们在查询表时最难理解的概念之一——即理解没有任何保证可以保证查询的数据将按特定顺序使用。例如,有些人认为当他们查询具有聚集索引的表时,他们将以聚集索引顺序返回数据。从语言的角度来看,这并不能保证,因为您查询的是集合,而您返回的也是集合。SQL Server 知道该语言不提供任何排序​​保证,因此它会以任何它喜欢的顺序扫描数据——包括不按聚集索引顺序。人们经常使用违反基于集合和关系概念的技术,因为结果的正确性依赖于按索引顺序使用数据,而 SQL Server 从未保证过这一点。我在我的网络独家文章中介绍了几个经典示例“多行变量赋值和ORDER BY“ 和 ”有序更新和基于集合的运行聚合解决方案”。

Ben-Gan 写道SQL 服务器 70-461培训手册中也强调了这一点。

我希望我能告诉你更好的事情,但是......不,没有“默认顺序”,因此你不应该依赖它,而且它也没有记录。

答案2

集合的顺序是不明确的未记录的。此处的“无证”有两层含义:

  1. 我们无法为您提供具体链接或引述,详细说明变更或新行为,因为未明确声明。这是通过设计,并符合关系“集”的概念。
  2. 由于没有记录,微软可以随时更改此行为。通过 Windows Update 提供的平淡无奇的补丁可以改变这种情况(虽然它没有改变,但它可以(即不违反任何政策)。即使你今天发现了某种特定行为,也不应该依赖它,因为它明天可能会毫无预警地发生变化。

这种自由对于 Microsoft 等数据库供应商来说非常重要。它使他们能够创新并对其产品进行性能改进。

这就引出了我的下一个观点。长期以来,一直存在这样一种观点,即没有 ORDER BY 子句的查询将根据查询中主表的主键(聚集索引)返回结果。这是错误的,并且始终为假。结果通常以这种方式返回,但只是因为这通常是处理查询的最快方式。但总是有例外:覆盖索引、循环表扫描、复杂的连接和子查询,其中查询的“主”表可能会根据本月编译的统计数据而发生变化,等等。

近年来,递归 CTE、窗口函数和 APPLY 操作等新概念已经引发了许多新情况,其中聚集索引顺序不再是处理查询的最快方式。这种影响不仅仅局限于使用这些新功能的查询。随着查询引擎增加复杂性以适应新功能,它获得了支持这些功能的新工具,这些功能在为旧查询准备计划时也非常有用。

答案3

补充一点,在 sql 2k8 enterprise 上有一个名为 mery go around 的新功能。
此功能本质上是重用来自其他线程的表扫描查询。
http://www.sanssql.com/2013/07/merry-go-round-scans-in-sql-server.html

相关内容