Эффект эффективности использования TOP 1 в запросе SELECT

У меня есть таблица User, где есть столбцы Username и Application. Имя пользователя может повторяться, но комбинация Username + Application уникальна, но у меня нет уникального ограничения, установленного в таблице (для производительности)

Вопрос: будет ли какая-либо разница (по производительности) между:

SELECT * FROM User where UserName='myuser' AND Application='myapp'

И -

SELECT TOP 1 * FROM User where UserName='myuser' AND Application='myapp'

Поскольку комбинация Username + Application уникальна, оба запроса всегда возвращают не более одной записи, поэтому TOP 1 не влияет на результат. Я всегда думал, что добавление TOP 1 действительно ускорит работу, так как сервер sql перестанет следить за тем, как найдет одно совпадение, но недавно я прочитал в статье, что использование TOP действительно замедлит работу, и рекомендуется избегать, хотя у них нет объяснил почему.

Любые комментарии?

Спасибо! Андрей

Ответы

Ответ 1

Вы можете получить некоторые отличия в производительности от использования top, но реальную производительность вы получаете с помощью индексов.

Если у вас есть индекс для полей UserName и Application, база данных даже не должна касаться таблицы, пока она не изолирует одну запись. Кроме того, из таблицы статистики уже будет известно, что значения уникальны, поэтому использование top не имеет значения.

Ответ 2

Если в результатах больше одной строки и нет предложения ORDER BY, "TOP 1" экономит массу работы для сервера. Если есть предложение order by, сервер все равно должен полностью реализовать весь результирующий набор, и если есть только одна строка, это ничего не изменит.

Ответ 3

Я думаю, что это зависит от плана выполнения запроса, который генерирует SQL... В прошлом в предыдущих версиях SQL Server я видел, как использование избыточного "TOP" обеспечивает определенные преимущества производительности при сложных запросах со многими объединениями. Но определенно не во всех случаях.

Я думаю, лучший совет, который я могу дать, - попробовать его в каждом конкретном случае.

Ответ 4

вы говорите, что не применяете ограничение, которое означает, что нет уникального индекса (UserName, Application) или (Application, UserName). Может ли запрос использовать путь доступа, который ищет либо на UserName, либо Application? Другими словами, индексируется любой из этих двух столбцов? Если да, то план будет выбирать наиболее избирательный, который индексируется и выполняет сканирование диапазона, возможно, вложенный цикл с поиском по закладке, если индекс не кластеризован, а затем фильтр. Top 1 остановит запрос после того, как будет сопоставлен первый фильтр, но зависит ли это от размера данных (сколько записей проверяет диапазон сканирования и сколько из них удовлетворяют фильтру).

Если индекс отсутствует, он будет выполнять полную кластерную проверку независимо от того, что. Верх 1 останавливает сканирование при первом совпадении, независимо от того, идет ли это после обработки 1 записи или после обработки 999 мил. записи depdends о фактическом имени пользователя и приложении...

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