Чому ЗАМОВЛЕННЯ НЕ належить до Перегляду?


51

Я розумію, що ви не можете мати ORDER BY погляд. (Принаймні, у SQL Server 2012, з яким я працюю)

Я також розумію, що "правильним" способом сортування подання є розміщення ORDER BYнавколо SELECTзаяви, яка запитує подання.

Але, будучи відносно новим у практичному SQL та звичаях поглядів, я хотів би зрозуміти, чому це робиться дизайном. Якщо я правильно слідкував за історією, це було колись можливо і було явно видалено з SQL Server 2008 і так далі (не цитуйте мене в точній версії).

Однак найкраща причина, з якої я можу придумати, чому Microsoft видалила цю функцію, - це те, що "вид - це несортований збір даних".

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


2
Перша відповідь - це місце ідеально. Я б запропонував, якщо ви хочете замовити вигляд, чому ви просто не зробите цього. Виберіть [Стовпці] з [YourView] Замовлення по [Стовпці]
Зене

Коротка відповідь: "З тієї ж причини, що ЗАМОВЛЕННЯ НЕ належить до таблиці".
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

одна можливість полягає в тому, щоб уникнути суперечливих сортування - якщо представлення сортується за одним порядком, а вибір у цьому представленні сортується за іншим порядком (не знаючи про тип перегляду), може виникнути враження від продуктивності. Тож безпечніше залишати вимогу сортування користувачеві.

Ще одна причина: сортування пов'язане з вартістю продуктивності, тож навіщо штрафувати всіх користувачів із перегляду, коли лише деяким користувачам потрібен сорт.


5

ANSI SQL дозволяє виконувати ORDER BYзапит на самий зовнішній запит з різних причин. Одна з них - це те, що відбувається, коли підселектор / view / CTE приєднується до іншої таблиці, а зовнішній запит є ORDER BYсам.

Сервер SQL ніколи не підтримував його всередині представлення (якщо ви не обдурили його, використовуючи TOP 100 PERCENTякий, на мою думку, в основному викликає помилку).

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

Дивіться цю публікацію в блозі команди оптимізатора запитів для повного технічного пояснення ТОП-100 відсотків ЗАМОВЛЕННЯ Вважається шкідливим.

Реалізація плану за замовчуванням для цього коду відбувається для сортування рядків як частини виконання операції TOP. Часто це означало, що результати повертаються в упорядкованому порядку, і це спонукало клієнтів вважати, що існує гарантія, що рядки будуть відсортовані. Це насправді не так. Якщо ви хочете, щоб рядки були повернуті користувачеві в упорядкованому порядку, вам потрібно скористатися ЗАМОВЛЕННЯМИ на найбільш віддалений блок запитів (на ANSI), щоб гарантувати вихідний порядок презентації.


3

Перегляди ведуть себе як таблиці, вміст яких визначається за результатами запиту.

Столи не мають порядку; вони просто мішки з рядами.

Тому перегляди також не мають порядку. Ви можете сортувати їх, вибравши рядки в певному ЗАМОВЛЕННІ.


1
Таблиці ... - це просто мішки з рядками - і тоді viwes - це просто віртуальні пакети віртуальних рядків - перегляди "не існують" - наприклад, для них дані взагалі не зберігаються - вони просто "зберігаються визначення запиту до бути виконаним ", в основному.
marc_s

1
+1 Еквівалентність табелей та поглядів здається мені основною причиною, чому перегляди не повинні містити "замовлення на"
miracle173,

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 відсотками або без верху), і це замовлення застосовується лише в тому випадку, якщо представлення вибрано безпосередньо, без явного порядку, без об'єднання, без сукупності, ні Перегляд ланцюжків тощо. Обидві випадки, перераховані вище, можуть підтримуватися цією простою моделлю.


-6

ви можете створити подання, яке має порядок і зберігає порядок за запитом після:

виберіть топ 99,999999999999 відсотків * від ..... замовити за


1
Чому б не просто SELECT TOP 100 PERCENT ...?
Макс Вернон

2
@Max, ймовірно, схожий на цей трюк - це не робить його гарною ідеєю.
Аарон Бертран

Погодився, @AaronBertrand - лише зазначивши, що не потрібно використовувати 99.99999999999 :-)
Макс Вернон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.