1

在尝试生成种子随机排序时,我注意到了这个问题,现在在 SQL Server 2008 R2 (RTM) 和SEDE上都复制了,即 SQL Server 2012 (SP1):

当您ORDER BY使用VarBinarySELECT字段时,不会发生排序。

在(上述 SEDE 的)查询计划中,您可以看到没有 SORT 用于:

SELECT [id]
  ,y.x As ryx
  ,RAND(y.x) As yx
FROM #Test, (SELECT CONVERT(varbinary, NEWID()) As x) y
ORDER BY ryx

就像我尝试过的所有其他变体一样(您可以在 SEDE 查询中看到它们,也可以将它们编辑为ORDER BY yx)。

我查看了MSDN并且仅在索引时确认VarBinary使用MACHINE 排序规则。

这只是一个错误还是一个记录不充分的功能?:-)

4

2 回答 2

1

这是一个错误。

Create Table #Test(Id Int NOT NULL)
 INSERT Into #Test VALUES(1)
 INSERT Into #Test VALUES(2)

SELECT @@VERSION

SELECT *
FROM (
    SELECT [id]
        ,y.x As ryx
        ,RAND(y.x) As yx
    FROM #Test, (SELECT CONVERT(varbinary,NEWID()) As x) y
) x
ORDER BY ryx --order by outside!

请参阅https://data.stackexchange.com/stackoverflow/query/162636/testing-sub-select-order-failure?opt.textResults=true&opt.withExecutionPlan=true

示例结果:

id          ryx
----------- -----------------------------------
1           0xC15FAED68C9A134882A2C977C46F1B8D --wrong order
2           0x532169D935535543BE0E0B24CA5D04FB --wrong order

在这个查询中,order by显然是在外面。x派生表的生成方式无关紧要。order by必须申请。行以未排序的顺序返回。

将其报告给 Microsoft Connect。这是一个优化器错误。

于 2014-01-24T11:08:56.370 回答
0

在将其添加到 Connect 的过程中,我注意到 NEWID()表达式是危险的,因为“设计”每次访问表达式时都会重新评估表达式,而不仅仅是每个“本地”行一次。

这将在此处进一步讨论,其中解释了 SQL Server 的设计者决定对准确性进行优化(与大多数编程语言编译器相反)。

因此,在我看到我的Connect 提交的实际结果之前,我猜测这是在转换为 VarBinary 时处于“错误”位置时略微过度优化的结果。

具体来说,这有效

SELECT *
FROM (
  SELECT [id]
    ,CONVERT(varbinary,y.x) As ryx
    ,RAND(CONVERT(varbinary,y.x)) As yx
  FROM #Test, (SELECT NEWID() As x) y
)x
ORDER BY ryx

usr在他的回答中的查询没有。

于 2014-01-25T02:46:15.490 回答