Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
选择查询中的默认行顺序-SQL Server 2008与SQL 2012_Sql_Sql Server_Sql Server 2008_Sql Server 2012_Database Migration - Fatal编程技术网

选择查询中的默认行顺序-SQL Server 2008与SQL 2012

选择查询中的默认行顺序-SQL Server 2008与SQL 2012,sql,sql-server,sql-server-2008,sql-server-2012,database-migration,Sql,Sql Server,Sql Server 2008,Sql Server 2012,Database Migration,我们的团队最近将数据库从SQL Server 2008升级到SQL Server 2012。我们注意到的一个重大变化是SELECT语句返回的默认行顺序,即未指定显式ORDERBY子句 根据MSDN,除非指定了ORDERBY子句,否则不指定返回行的顺序 我们有5个数据库中的2500多个存储过程,这些数据库中的SELECT语句没有ORDER BY子句,手动添加ORDER BY子句以匹配SQL Server 2008中的行为将是一项相当大的工作。是否有一种设置或更快的方法来实现这一点 另一个尚未探讨的

我们的团队最近将数据库从SQL Server 2008升级到SQL Server 2012。我们注意到的一个重大变化是SELECT语句返回的默认行顺序,即未指定显式ORDERBY子句

根据MSDN,除非指定了ORDERBY子句,否则不指定返回行的顺序

我们有5个数据库中的2500多个存储过程,这些数据库中的SELECT语句没有ORDER BY子句,手动添加ORDER BY子句以匹配SQL Server 2008中的行为将是一项相当大的工作。是否有一种设置或更快的方法来实现这一点


另一个尚未探讨的选项是降级到SQLServer2008。这有多困难?

您需要返回并在代码中添加
ORDER BY
子句,因为没有它们,订单永远无法得到保证。在过去,您总是得到相同的订单,这是“幸运的”,但这并不是因为SQL Server 2008保证了这一点。这很可能与索引或数据在磁盘上的存储方式有关

如果在升级时移动到新主机,仅硬件配置的差异就可能改变查询的执行方式。更不用说新服务器将重新计算表的统计信息,SQL server 2012查询优化器的工作方式可能与SQL server 2008中的有所不同

这是一种谬误,即您可以依赖SQL中结果集的顺序,而不显式地说明您希望它的顺序。SQL结果决不具有可依赖的顺序,而无需使用
order BY
子句。SQL是围绕集合论构建的。查询结果基本上是集合(或多集合)

伊齐克·本·甘在他的书中很好地描述了集合论与SQL的关系

由数学家乔治·坎托(Georg Cantor)创立的集合论是 关系模型所基于的数学分支之一 基于。康托对集合的定义如下:

我们所说的“集合”是指将任何集合M分解为一个确定的、不同的集合的整体 我们感知的对象m(称为m的“元素”)或 我们的思想Joseph W.Dauben和Georg Cantor(普林斯顿大学) 大学出版社,1990年)

在彻底解释了定义中的术语之后,伊兹克接着说:

康托对集合的定义遗漏了什么可能也同样重要 正如它所包括的。请注意,定义中没有提到任何 集合元素之间的顺序。集合元素的排列顺序 这并不重要。列出集合元素的形式表示法 使用花括号:{a,b,c}。因为秩序与你无关 表示与{b,a,c}或{b,c,a}相同的集合。跳到前面 一组属性(在SQL中称为列),组成 关系(在SQL中称为表),元素应该是 按名称标识-不是顺序位置。同样,考虑集合 组成关系主体的元组(SQL称为行); 元素由其键值标识,而不是由位置标识。许多的 程序员很难适应这样的想法,即 对于查询表,行之间没有顺序换句话说, 对表的查询可以按任何顺序返回行,除非 明确地请求以特定的方式对数据进行排序,也许 用于演示目的。

但不管集合的学术定义如何,即使是SQL server中的实现也从未保证结果的任何顺序。这说明您根本不应该依赖中间操作的顺序

重新排序规则可以也将违反这一假设(并且会违反这一假设) 当对您不方便时,开发人员;)。请理解 当我们重新安排业务以找到更有效的计划时,我们可以 使中的中间节点的排序行为发生更改 树。如果您在树中放置了一个假定 特别是中间顺序,它可能会中断

Conor Cunningham(SQL Server核心引擎架构师)的这篇博文是关于SQL Server 2008的。他有一个表,其中有20k行,有一个索引,似乎总是以相同的顺序返回行。向查询中添加一个
orderby
甚至不会改变执行计划,因此,如果优化器意识到它不需要,那么这不像在中添加一个那样会使查询更加昂贵。但是,一旦他向表中再添加20k行,查询计划就会突然改变,现在它使用并行性,结果不再有序

这里最困难的部分是,没有任何合理的方式来处理任何外部问题 用户需要知道计划何时会更改。所有计划的空间都是巨大的 并且伤了你的头去思考。SQL Server的优化器将更改 计划,即使是简单的查询,如果有足够多的参数改变。 你可能很幸运,没有改变计划,也可能就是没有 考虑一下这个问题,然后按添加订单

如果你需要更多的说服力,请阅读以下文章:


没有“默认行顺序”这样的东西。关系表中的行未排序。除非您指定一个order by,否则DBMS可以按照任何合适的顺序自由返回它们。你的代码从一开始就被破坏了。唯一合理的解决方案是咬紧牙关,将代码更改为使用
order by
,幸运的是,此错误没有提前出现。SQL 2008也一样,没有保证使用clustured和non-clustured索引的“默认”行排序,如果您的表中已经有主键,则不必担心clustured,因为默认情况下主键是clustured index。
ORDER by
应该只与
SELECT