Навіщо використовувати Select Top 100 Percent?


82

Я розумію, що до SQL Server 2005 ви могли "обдурити" SQL Server, щоб дозволити використовувати порядок у визначенні подання, також включивши TOP 100 PERCENTв речення SELECT . Але я бачив інший код, який я успадкував, який використовує SELECT TOP 100 PERCENT... в рамках динамічних операторів SQL (використовується в ADO у програмах ASP.NET тощо). Чи є для цього якась причина? Хіба результат не такий самий, як не врахування TOP 100 PERCENT?


5
можливо, відбувається якась конструкція висловлювання: "ВИБЕРИ ТОП {0}
ПРОЦЕНТ

Ваше перше речення стало відповіддю на одне з моїх прихованих запитань.
Мухаммед Асікуззаман

Я використовую найкращі 99,9999999 відсотків, і це завжди працює. Це досить близько. Я схильний додавати цифри 9 на основі очікуваної кількості записів. Більше записів, більше 9-ти, і це завжди працює. Я використовував по SQL 2008 для SQL 2017.
педи

Відповіді:


51

Він використовувався для " проміжної матеріалізації (пошук Google) "

Хороша стаття: Адам Маханік: Дослідження секретів проміжної матеріалізації

Він навіть підняв MS Connect, щоб це можна було зробити чистіше

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

Працював приклад

Це може не вдатися, оскільки ви не знаєте, в якому порядку оцінюються речі

SELECT foo From MyTable WHERE ISNUMERIC (foo) = 1 AND CAST(foo AS int) > 100

І це також може зазнати невдачі, тому що

SELECT foo
FROM
    (SELECT foo From MyTable WHERE ISNUMERIC (foo) = 1) bar
WHERE
    CAST(foo AS int) > 100

Однак цього не було в SQL Server 2000. Внутрішній запит обчислюється та буксується:

SELECT foo
FROM
    (SELECT TOP 100 PERCENT foo From MyTable WHERE ISNUMERIC (foo) = 1 ORDER BY foo) bar
WHERE
    CAST(foo AS int) > 100

Зауважте, це все ще працює в SQL Server 2005

SELECT TOP 2000000000 ... ORDER BY...

Чому другий запит не вдається? Оскільки внутрішній запит не (обов’язково) оцінений повністю?
Кенні Евітт,

Це друге посилання пояснює, чому створення тимчасових таблиць іноді призводить до значного покращення продуктивності!
Kenny Evitt

41

TOP (100) PERCENT є абсолютно безглуздим в останніх версіях SQL Server, і він (разом із відповідним ORDER BY, у випадку визначення подання або похідної таблиці) ігнорується процесором запитів.

Ви праві, що колись давно це можна було використовувати як фокус, але навіть тоді це було не надійно. На жаль, деякі графічні інструменти Microsoft вкладають цей безглуздий пункт.

Щодо того, чому це може з’являтися в динамічному SQL, я не маю уявлення. Ви праві, що для цього немає причин, і результат однаковий і без нього (і знову ж, у випадку визначення подання або похідної таблиці, без пропозицій TOP і ORDER BY).


Це неправда; див. це посилання з відповіді @gbn для деталей.
Кенні Евітт,

4
Посилання, на яке ви посилаєтесь, нічого не говорить про ВИБІР ТОПУ (100) ПРОЦЕНТІВ. ЗАМОВИТИ, що безглуздо. Посилання згадує використання SELECT TOP (2147483647) .. ЗАМОВИТИ ПО. В даний час оптимізатор SQL Server усуне SELECT TOP (100) PERCENT .. ORDER BY, оскільки це безглуздо. Ця комбінація завжди визначає ту саму колекцію рядків, що і SELECT без TOP / ORDER BY. В даний час оптимізатор не намагається визначити, чи містить 2147483647 всі рядки, тому в цьому випадку він не усуває комбінацію TOP - ORDER BY.
Steve Kass

2
Посилання насправді згадує TOP (100) PERCENT: "... Я можу спробувати примусити проміжну матеріалізацію похідної таблиці, без тимчасової таблиці, використовуючи TOP 100 PERCENT у поєднанні з ORDER BY. На жаль, команда оптимізатора запитів SQL Server вирішила, що це не" Це гарна ідея, і оптимізатор тепер ігнорує такі спроби ". Це насправді підтримує вас.
Кенні Евітт,

Я б скасував свій голос проти, якби міг . [Якщо ви відредагуєте свою відповідь, я підтримую.]
Кенні Евітт,

1
Ви, мабуть, розгублені, бо я передумав; мій перший коментар був помилковим; ти маєш рацію.
Кенні Евітт

23

... дозволяють використовувати ORDER BY у визначенні подання.

Це не гарна ідея. У поданні ніколи не повинно бути визначено ORDER BY.

ORDER BY впливає на ефективність - використання його подання означає, що ORDER BY з’явиться в плані пояснення. Якщо у вас є запит, де подання приєднано до чого-небудь у безпосередньому запиті, або на яке посилається у вбудованому поданні (факторизація CTE / підзапиту) - ORDER BY завжди виконується до остаточного ORDER BY (за умови, що це було визначено). Немає переваги впорядковувати рядки, які не є остаточним результатом, коли запит не використовує TOP (або LIMIT для MySQL / Postgres).

Розглянемо:

CREATE VIEW my_view AS
    SELECT i.item_id,
           i.item_description,
           it.item_type_description
      FROM ITEMS i
      JOIN ITEM_TYPES it ON it.item_type_id = i.item_type_id
  ORDER BY i.item_description

...

  SELECT t.item_id,
         t.item_description,
         t.item_type_description
    FROM my_view t
ORDER BY t.item_type_description

... еквівалентно використанню:

  SELECT t.item_id,
         t.item_description,
         t.item_type_description
    FROM (SELECT i.item_id,
                 i.item_description,
                 it.item_type_description
            FROM ITEMS i
            JOIN ITEM_TYPES it ON it.item_type_id = i.item_type_id
        ORDER BY i.item_description) t
ORDER BY t.item_type_description

Це погано, оскільки:

  1. Приклад - це упорядкування списку спочатку за описом товару, а потім його впорядкування на основі опису типу товару. Це марно витрачені ресурси у першому сортуванні - запуск як є не означає, що він працює:ORDER BY item_type_description, item_description
  2. Не очевидно, яким чином впорядкований вигляд через інкапсуляцію. Це не означає, що вам слід створювати кілька подань з різними порядками сортування ...

6

Якщо ORDER BYречення відсутнє , TOP 100 PERCENTце зайвий. (Як ви вже згадували, це був «фокус» з поглядами)

[Сподіваємось, оптимізатор оптимізує це.]


5

Я бачив інший код, який я успадкував, який використовує ВИБІР ТОП 100 ВІДЦІ

Причина цього проста: Менеджер підприємств намагався бути корисним та відформатувати ваш код, щоб включити це для вас. Немає сенсу ніколи намагатися видалити його, оскільки це насправді нічого не зашкодило, і наступного разу, коли ви підете його міняти, ЕМ вставить його знову.


4

Ніяких причин, крім байдужості, я думаю.

Такі рядки запитів зазвичай генеруються графічним інструментом запитів. Користувач приєднується до кількох таблиць, додає фільтр, порядок сортування та перевіряє результати. Оскільки користувач може захотіти зберегти запит у вигляді подання, інструмент додає ТОП 100 ПРОЦЕНТІВ. Однак у цьому випадку користувач копіює SQL у свій код, параметризує речення WHERE і приховує все на рівні доступу до даних. З розуму, з поля зору.


1

Будь ласка, спробуйте нижче, сподіваємося, це буде працювати для вас.

      SELECT TOP
              ( SELECT COUNT(foo) 
                  From MyTable 
                 WHERE ISNUMERIC (foo) = 1) * 
                  FROM bar WITH(NOLOCK) 
              ORDER BY foo
                 WHERE CAST(foo AS int) > 100
               )

1

Помилка говорить все ...

Повідомлення 1033, рівень 15, стан 1, процедура TestView, рядок 5 Речення ORDER BY недійсне у поданнях, вбудованих функціях, похідних таблицях, підзапитах та загальних виразах таблиць, якщо також не вказано TOP, OFFSET або FOR XML.

Не використовуйте TOP 100 PERCENT, використовуйте TOP n, де N - число

ТОП 100 відсотків (з причин, яких я не знаю) ігнорується SQL Server VIEW (версії після 2012 року), але, на мою думку, MS зберегла його з синтаксичних причин. TOP n краще і буде працювати всередині подання та сортувати його так, як ви хочете, коли подання використовується спочатку, але будьте обережні .


0

Я вважаю, що ви можете використовувати змінну в результаті, але крім отримання фрагмента ORDER BY у поданні, ви не побачите вигоди, якщо неявно зазначите "TOP 100 PERCENT":

declare @t int
set @t=100
select top (@t) percent * from tableOf

2
Питання Why use Select Top 100 Percentне в тому, щоб отримати кількість змінних для відсотків.
bummi

0

Просто спробуйте це, це пояснює це сам по собі. Ви не можете створити представлення за допомогою ORDER BY, крім випадків, якщо ...

CREATE VIEW v_Test
         AS
           SELECT name
             FROM sysobjects
         ORDER BY name
        GO

Повідомлення 1033, рівень 15, стан 1, процедура TestView, рядок 5 Речення ORDER BY недійсне у поданнях, вбудованих функціях, похідних таблицях, підзапитах та загальних виразах таблиць, якщо також не вказано TOP, OFFSET або FOR XML.

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