Всегда ли SELECT TOP - самый быстрый способ получить предварительный просмотр нужного запроса на SQL?

У меня есть следующий запрос, который я выполнил:

SELECT TOP 100 certs.CertId, COUNT(cluster.BGTJobId) C
FROM [CentralDB_US_33].[dbo].[JobSkillClusterIndex] cluster 
INNER JOIN [Eagle].[raw].[certs] certs 
  ON certs.BGTJobId = cluster.BGTJobId
GROUP BY cluster.skillClusterId, certs.CertId

В конечном счете, я хочу получить полные результаты, а не только топ-100, но для предварительного просмотра, это самый быстрый способ?

# sql-server
Источник
  • 2
    Предложение SELECT TOP используется для указания количества возвращаемых записей ...
  • 4
    Я не знаю, что такое превью.
  • 3
    Это зависит от того, что вы подразумеваете под предварительным просмотром - что вы имеете в виду?
  • 4
    Гарантирую, что TOP 1 будет быстрее.
  • 0
    @ Strawberry Я просто имею в виду меньшее количество строк, чтобы понять, имеет ли смысл моя база данных и запрос
  • 4
    Нет, не гарантируется, что он будет быстрее - этот вопрос является показательным - несмотря на то, что исходный запрос возвращает только 35 строк, добавление первых 30 фактически увеличивает время выполнения в 10-100 раз. Добавление TOP обычно ускоряет выполнение запроса, но может полностью изменить план выполнения, введение TOP приводит к переключению с соединения слиянием на соединение с вложенным циклом, а также к значительному увеличению времени выполнения.
  • 0
    @GarethD Вопрос, на который вы указали, имеет ORDER BY , тогда как запрос в этом сценарии - нет. Я все равно готов поспорить, что в этом сценарии TOP 1 будет быстрее.
  • 0
    @RaduGheorghiu только что пробежал ТОП 1, и это заняло 14 минут, как и ТОП 100. Время платить
  • 0
    @Ecanales Вы использовали SET STATISTICS TIME ON чтобы проверить разницу? В любом случае, поскольку вы упомянули время выполнения запроса, ваша проблема в другом месте. GROUP BY , которую вы делаете, создает неявную сортировку данных, что в вашем случае (я предполагаю, что у вас много строк).
  • 2
    @Ecanales Вы можете добавить больше информации и показать план выполнения запроса, вставив XML плана здесь и сравнялась с остальной частью нас. Тем не менее, TOP 1 быстрее, потому что он извлекает меньше строк и отображает меньше строк. Даже если он немного быстрее, чем TOP 100 , он все равно есть.
  • 0
    Основываясь исключительно на том факте, что топ-100 и топ-1 занимают 14 минут, я предполагаю, что оптимизатор выполняет хеш-агрегат с одним или несколькими сканированиями кластерного индекса на больших таблицах, независимо от того, какой лимит вы применяете, полный сканирование все еще необходимо для получения точного подсчета, потому что что-то, что в конечном итоге оказывается на вершине x, может быть как первой, так и последней отсканированной записью.
  • 0
    Вам либо нужно просмотреть свои индексы, либо, если это только для целей предварительного просмотра, вы можете рассмотреть возможность использования TABLESAMPLE - вместо того, чтобы выбирать верхние x строк результата, он просто вернет примерное количество строк из каждой таблицы, тем самым уменьшив количество работы в совокупности.
  • 0
    Я думаю, что и @GarethD, и RaduGheorghiu частично правы. Гарет прав, когда говорит, что он должен запускать весь процесс, независимо от ТОП-100. И Раду прав, когда говорит, что долгое время выполнения частично связано с дизайном таблицы. Я обнаружил небольшую разницу между выполнением TOP и обычным запросом с точки зрения времени выполнения.
  • 0
    Вы говорите, что это сделано для предварительного просмотра, но имейте в виду, что TOP без ORDER BY - это «те строки, которые наиболее удобно получить». Это может означать, что полученная вами выборка строк не репрезентативна для всей совокупности строк.
Codelisting
за 1 против

Поскольку вы упомянули, что это сделано для предварительного просмотра, я предполагаю, что вам просто нужны данные из запроса, и вы хотите, чтобы он выполнялсяFAST независимо от данных, которые он возвращает, и, видя, что вы упомянули, что запрос занимает 14 минут для выполнения, быстрое «исправление» будет заключаться в использовании чего-то вроде ниже:

SELECT
    certs.CertId
    , COUNT(cluster.BGTJobId)
FROM
    (SELECT TOP 100 
        certs.CertId
    FROM [Eagle].[raw].[certs] certs) certs
INNER JOIN [CentralDB_US_33].[dbo].[JobSkillClusterIndex] cluster 
    ON certs.BGTJobId = cluster.BGTJobId
GROUP BY cluster.skillClusterId, certs.CertId

Агрегирование данных (в вашем случаеCOUNT ) - очень дорогостоящая операция, и ее следует выполнять только в последней части запроса на как можно меньшем количестве данных. Поэтому для целей "предварительного просмотра" я выбрал только первые 100 сертификатов и сделалCOUNT по этим данным.

Однако , поскольку вы упомянули, что выполнение запроса занимает 14 минут, проблемы возникают в другом месте, и обычно это связано с дизайном (дизайн запроса, дизайн индекса или даже дизайн таблицы).

  • Вы должны спросить себя, действительно ли вы хотите просмотреть все данные в таблицах и получить все совпадающие строки из обеих таблиц, и не пропустите ли выWHERE пункт?

  • Если вы все же решите, что естьWHERE необходимо предложение, существуют ли какие-либо индексы, помогающие фильтровать данные на основе условий вашегоWHERE предложение (и даже столбцы соединения -certs.BGTJobId а такжеcluster.BGTJobId ?

за 0 против

Да, верхний запрос выбора является самым быстрым для предварительного просмотра, поэтому он также отображается в графическом интерфейсе студии управления правой кнопкой мыши. Но если вы выполняете пользовательский запрос, просто проверьте, что где выполняется предложение / группировка и т. Д., Является частью кластеризованного индекса.

  • 0
    Не обращайте внимания на названия таблиц, это субъективно определенные таксономии базы данных, с которой я работаю.
Codelisting
Популярные категории
На заметку программисту