Упорядочить по выражению 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!
Пример результатов:
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
где, как запрос пользователя в своем ответе не.