Order By VarBinary表达式未排序

时间:2014-01-24 11:02:26

标签: sql sql-server sorting varbinary newid

尝试generate a seeded random ordering时我注意到了这个问题,现在在SQL Server 2008 R2(RTM)和SEDE上都进行了复制,即SQL Server 2012(SP1):

当您ORDER BY VarBinary子 - SELECT字段时,订单不会发生。

在查询计划(上面的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 collation

这只是一个错误或记录不完整的功能吗? : - )

2 个答案:

答案 0 :(得分: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!

请参阅http://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。这是一个优化错误。

答案 1 :(得分:0)

在将此添加到Connect的方式上,我note NEWID()在表达式中很危险,因为 “按设计”表达式每次都会重新评估它们被访问,而不是每个“本地”行一次。

这进一步讨论here,其中解释了SQL Server的设计者决定优化精度(与大多数编程语言编译器相反)。

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

具体来说,这是works

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's query没有。