Почему ORDER BY не принадлежит представлению?

51

Я понимаю, что вы не можете иметь ORDER BY в виду. (По крайней мере, в SQL Server 2012 я работаю с)

Я также понимаю, что «правильный» способ сортировки представления заключается в том, чтобы ORDER BYобойти SELECTоператор, запрашивающий представление.

Но, будучи относительно новым для практического использования SQL и использования представлений, я хотел бы понять, почему это сделано так по замыслу. Если я правильно следил за историей, это когда-то было возможно и было явно удалено из SQL Server 2008 и т. Д. (Не указывайте точную версию).

Однако, лучшая причина, по которой я могу придумать, почему Microsoft удалила эту функцию, заключается в том, что «представление - это несортированный набор данных».

Я предполагаю, что есть веская логическая причина того, почему представление должно быть не отсортировано. Почему представление не может быть просто уплощенным набором данных? Почему конкретно не отсортировано? Не кажется сложным придумывать ситуации, когда (по крайней мере, мне / ИМХО) кажется совершенно интуитивно понятным иметь отсортированный вид.

ngmiceli
источник
2
Первый ответ - идеальный. Я хотел бы предложить, если вы хотите заказать представление, почему бы вам просто не сделать это. Выберите [Столбцы] из [YourView] Порядок по [Столбцам]
Зейн
Краткий ответ: «По той же причине, что ORDER BY не принадлежит таблице».
ypercubeᵀᴹ

Ответы:

38

(Индексированные представления в стороне, конечно.)

Представление не материализуется - данные не сохраняются, так как их можно отсортировать? Представление похоже на хранимую процедуру, которая просто содержит SELECTбез параметров ... оно не содержит данных, оно просто содержит определение запроса. Поскольку для разных ссылок на представление могут потребоваться данные, отсортированные по-разному, способ, которым вы делаете это - точно так же, как при выборе из таблицы, которая по определению также является несортированной коллекцией строк, - это включение порядка по во внешний запрос. ,

Также, чтобы дать немного понимания истории. Вы никогда не могли бы поставить ORDER BYв точку зрения, в том числе и в том числе TOP. И в этом случае ORDER BYдиктуется, какие строки были включены TOP, а не как они будут представлены. Так уж получилось, что в SQL Server 2000, если TOPбыл 100 PERCENTили {some number >= number of rows in the table}, оптимизатор был довольно упрощен, и в итоге он создал план с видом, который соответствует TOP/ORDER BY. Но такое поведение никогда не гарантировалось и не документировалось - на него просто полагались, основываясь на наблюдениях, что является плохой привычкой . Когда вышел SQL Server 2005, это поведение стало «ломаться» из-за изменений в оптимизаторе, которые привели к использованию различных планов и операторов - среди прочего,TOP / ORDER BYбудет игнорироваться полностью, если бы это было TOP 100 PERCENT. Некоторые клиенты жаловались на это так громко, что Microsoft выпустила флаг трассировки, чтобы восстановить прежнее поведение. Я не буду рассказывать вам, что это за флаг, потому что я не хочу, чтобы вы его использовали, и я хочу убедиться, что цель правильная - если вы хотите предсказуемый порядок сортировки, используйте ORDER BYего для внешнего запроса.

Подводя итог, а также проясните высказанное вами замечание: Microsoft ничего не удалила . Они сделали продукт лучше, и в качестве побочного эффекта это недокументированное, негарантированное поведение стало менее надежным. В целом, я думаю, что продукт лучше для него.

Аарон Бертран
источник
Здесь упоминается (в комментарии), что TOPвыполняет операцию курсора над набором результатов. Поэтому он может иметь явный порядок.
Тим Шмельтер
@TimSchmelter, который не помогает, когда оптимизатор видит TOP 100 PERCENT / ORDER BYи полностью удаляет его из плана. Попробуйте это.
Аарон Бертран
Это был просто знак. Остальная часть комментария так или иначе выглядит следующим образом: «Уловка SELECT TOP x запланирована как устаревшая в будущей версии SQL Server, поэтому было бы лучше вообще ее не использовать».
Тим Шмельтер
@TimSchmelter это уже не работает. Я не думаю, что он перестанет работать в любой новой версии в ближайшее время, потому что он сломает слишком много существующего кода.
Аарон Бертран
2
@TimSchmelter там порядок не говорит о порядке строк, он говорит о порядке столбцов в строке. В SQL Server мы обычно не говорим о том, что строка является кортежем, потому что физическая реализация строки для нас настолько очевидна (в таблице перечислены столбцы в порядке их определения).
Аарон Бертран
9

Если представление было разрешено сортировать, то каков должен быть порядок результатов здесь?

CREATE VIEW dbo.V1
AS
  SELECT number
  FROM   SomeTable
  ORDER  BY number ASC

GO

CREATE VIEW dbo.V2
AS
  SELECT number
  FROM   SomeTable
  ORDER  BY number DESC

GO

SELECT *
FROM   dbo.V1
       JOIN dbo.V2
         ON V1.number = V2.number 
Мартин Смит
источник
Я не понимаю этого. Вместо того, чтобы писать представление базы данных, вы можете написать обычный SQL-запрос. Каков должен быть порядок результата в этом случае? спасибо
hqt
7

одна возможность - избежать конфликтующих сортировок - если представление сортируется по одному порядку, а выборка по этому представлению сортируется по другому порядку (не зная о сортировке представления), это может привести к снижению производительности. Поэтому безопаснее оставить требование сортировки пользователю.

Еще одна причина, по которой сортировка связана с затратами на производительность, так зачем наказывать всех пользователей представления, когда сортировка нужна только некоторым пользователям.

srini.venigalla
источник
5

ANSI SQL допускает только самый ORDER BYвнешний запрос по ряду причин, одна из которых заключается в том, что происходит, когда подвыбор / представление / CTE соединяется с другой таблицей, а внешний запрос имеет свой ORDER BYсобственный.

SQL-сервер никогда не поддерживал его внутри представления (если только вы не обманули его, используя, TOP 100 PERCENTкоторый, по моему мнению, чаще всего вызывает ошибку).

Даже если вы вызвали ошибку, результаты никогда не были надежными, и сортировка не всегда получалась так, как вы ожидали.

См. Это сообщение в блоге команды оптимизатора запросов для получения полного технического объяснения. ТОП 100 процентов ПОРЯДОК считается опасным.

Реализация плана по умолчанию для этого кода происходит сортировка строк как часть выполнения операции TOP. Зачастую это означало, что результаты возвращались в отсортированном порядке, и это заставляло клиентов полагать, что была гарантия сортировки строк. Это на самом деле не тот случай. Если вы хотите, чтобы строки возвращались пользователю в отсортированном порядке, вам нужно использовать ORDER BY в самом внешнем блоке запроса (согласно ANSI), чтобы гарантировать выходной порядок представления.

Том V
источник
3

Представления ведут себя как таблицы, содержимое которых определяется результатами запроса.

Столы не имеют порядка; они просто мешки с рядами.

Поэтому у представлений тоже нет порядка. Вы можете отсортировать их, выбрав строки в определенном порядке.

duskwuff
источник
1
Таблицы ... это просто пакеты строк - и тогда viwes - это просто виртуальные пакеты виртуальных строк - представления "не существуют" - например, для них вообще нет данных - они просто "хранят определения запроса к исполняться ", в основном.
marc_s
1
+1 Равенство таблиц и представлений кажется мне главной причиной, почему представления не должны содержать «порядок по»
чудо173
1
«Представления ведут себя как таблицы» . Я бы сказал, что «Представления ведут себя как базовые таблицы. Представления - это таблицы».
ypercubeᵀᴹ
-2

Один из ответов, который еще не дан, заключается в том, что «упорядочение по» может мешать продвижению предикатов, что может сильно повлиять на производительность.

Примером является представление, которое сворачивает большой набор данных в сводку из 10 строк, которая является топ-10 / Упорядочено:

select * from TopOrderedView; -- Ordered 10 line summary in 5s

Для того же случая с сильным предикатом:

select * from TopOrderedView where <condition>; -- Ordered 2 line summary in still 5s

Это все равно занимает столько же времени, потому что top / order by блокирует предикат от более раннего запуска в конвейере. Это может привести к обработке ненужных строк, и план будет аналогичен плану без предиката.

Должен ли толчок произойти до того, как будет сделан заказ, это действительно выбор разработчика и может изменить ответ. Чаще всего толчок является логическим намерением.

Использование «верхних 100 процентов» логически позволяет использовать предикатный толчок, однако реализация, к сожалению, игнорирует «порядок по» для этого случая и побеждает намерение.

Для реальных случаев использования хорошим компромиссом для двигателя было бы выполнение «заказа на тягу». Это позволило бы указывать «порядок по» в представлении (с верхними 100 процентами или без верха), и этот порядок используется только в том случае, если представление выбирается напрямую, без явного упорядочения, без объединений, без агрегатов, без цепочка представления и т. д. Оба перечисленных выше случая могут поддерживаться этой простой моделью.

crokusek
источник
-6

Вы можете создать представление, которое имеет порядок по и сохраняет порядок при запросе после:

выберите топ 99,9999999999999 процентов * из ..... упорядочить по

NasF1
источник
1
Почему не просто SELECT TOP 100 PERCENT ...?
Макс Вернон
2
@Max, вероятно, похож на этот трюк - это не делает его хорошей идеей.
Аарон Бертран
Согласен, @AaronBertrand - просто отметив, что нет необходимости использовать 99.99999999999 :-)
Макс Вернон