Зачем использовать Select 100%?
Я понимаю, что до SQL Server 2005 вы могли "обмануть" SQL Server, чтобы разрешить использование порядка в определении представления, а также включить TOP 100 PERCENT
в предложении SELECT. Но я видел другой код, который я унаследовал, который использует SELECT TOP 100 PERCENT
... в динамических операторах SQL (используется в ADO в приложениях ASP.NET и т. д.). Есть ли причина для этого? Разве результат не совпадает с TOP 100 PERCENT
?
9 ответов
Он был использован для " промежуточной материализации (поиск 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...
TOP (100) PERCENT совершенно бессмысленен в последних версиях SQL Server, и он (вместе с соответствующим ORDER BY, в случае определения представления или производной таблицы) игнорируется обработчиком запросов.
Вы правы, что когда-то это можно было использовать как уловку, но даже тогда это было ненадежно. К сожалению, некоторые из графических инструментов Microsoft помещают это бессмысленное предложение.
Что касается того, почему это может появиться в динамическом SQL, я понятия не имею. Вы правы в том, что для этого нет никаких причин, и результат без него одинаков (и опять же, в случае определения представления или производной таблицы, без предложений TOP и ORDER BY).
... разрешить использование 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
Это плохо, потому что:
- В примере сначала упорядочивается список по описанию элемента, а затем он переупорядочивается на основе описания типа элемента. Это впустую потраченные ресурсы в первом роде - работа как есть, не означает, что она работает:
ORDER BY item_type_description, item_description
- Не очевидно, из-за чего представление упорядочено из-за инкапсуляции. Это не означает, что вы должны создавать несколько представлений с разными порядками сортировки...
Если нет ORDER BY
оговорка, то TOP 100 PERCENT
избыточно (Как вы упоминаете, это был "трюк" с представлениями)
[Надеюсь, оптимизатор оптимизирует это.]
Думаю, нет причин, кроме равнодушия.
Такие строки запроса обычно генерируются графическим инструментом запроса. Пользователь объединяет несколько таблиц, добавляет фильтр, порядок сортировки и проверяет результаты. Поскольку пользователь может захотеть сохранить запрос в виде представления, инструмент добавляет ТОП 100 ПРОЦЕНТОВ. Однако в этом случае пользователь копирует SQL-код в свой код, параметризирует предложение WHERE и скрывает все на уровне доступа к данным. С ума, с глаз долой.
Я видел другой код, который я унаследовал, который использует SELECT TOP 100 PERCENT
Причина этого проста: Enterprise Manager обычно старался быть полезным и форматировал свой код, чтобы включить это для вас. Не было никакого смысла пытаться удалить его, потому что это ничего не повредило, и в следующий раз, когда вы пошли его менять, EM вставит его снова.
Пожалуйста, попробуйте ниже, надеюсь, это будет работать для вас.
SELECT TOP
( SELECT COUNT(foo)
From MyTable
WHERE ISNUMERIC (foo) = 1) *
FROM bar WITH(NOLOCK)
ORDER BY foo
WHERE CAST(foo AS int) > 100
)
Ошибка говорит сама за себя...
Msg 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 лучше и будет работать внутри представления и сортировать его так, как вы хотите, когда представление используется изначально, но будьте осторожны.
Я бы предположил, что вы можете использовать переменную в результате, но кроме получения части ORDER BY в представлении, вы не увидите выгоды, неявно заявив "TOP 100 PERCENT":
declare @t int
set @t=100
select top (@t) percent * from tableOf
Просто попробуйте, это само по себе объясняет. Вы не можете создать представление с 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.