Упорядочить по выражению VarBinary не отсортировано

При попытке сгенерировать случайное упорядоченное число я отметил эту проблему, которая теперь реплицируется как в SQL Server 2008 R2 (окончательная первоначальная версия), так и в 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 при индексации.

Это просто ошибка или плохо документированная функция?:-)

2 ответа

Решение

Это ошибка.

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/stackru/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. Это ошибка оптимизатора.

На пути к добавлению этого в 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

где, как запрос пользователя в своем ответе не.

Другие вопросы по тегам