SQL: выполняется ли сначала основной или вложенный запрос?

#sql #sql-server

#sql #sql-server

Вопрос:

Предполагая, что у меня есть таблица «MyTable», содержащая 10 000 записей; когда я выполняю запрос ниже, чтобы получить всего 25 записей: сначала выбираются все 10 000 записей, прежде чем возвращать только 25 из них, или запрос будет оптимизирован автоматически анализатором SQL?

 SELECT *
FROM
   (
    SELECT HPE.ID, 
           HPE.EventTitle, 
           HPE.EventDate, 
           HPE.EventLocation, 
           HPE.SortOrder,
           CASE HPE.FlagShowInShop
               WHEN 1 THEN 'Yes'
               ELSE 'No'
           END AS FlagShowInShop, 
           HPE.ShowFrom, 
           HPE.ShowTo, 
           HPE.FK_Language, 
           HPE.FK_Region, 
           ISNULL (EG.Name, 'BIG EVENTS') AS EventGenre, 
           ROW_NUMBER () OVER
                              (ORDER BY HPE.FK_EventGenre_Value, 
                                        HPE.SortOrder
                              ) AS RowNum
      FROM [MyTable] AS HPE
           LEFT JOIN [MySecondTable] AS EG ON HPE.FK_EventGenre_Value=EG.Value
   ) AS HomePageEventsWithRowNumber
WHERE RowNum BETWEEN 1 AND 25
 

Комментарии:

1. лучший вариант — проверить фактический план выполнения. это может зависеть от имеющихся у вас индексов, но при использовании rownumber обычно требуется оценить всю таблицу, чтобы упорядочить данные для получения соответствующих строк.

Ответ №1:

В вашем случае для поиска строк с 1 по 25 должен быть выполнен внутренний select. Но — если есть индекс, и это можно предсказать — я бы предположил, что внешний запрос будет принят во внимание. Если движок может предсказать первые 25 строк, он попытается сократить объем работы.

Что бы вы ни делали или ни проверяли, нет точного прогноза. Вы можете проверить план выполнения и выяснить, какой из них выполняется первым, но в следующий раз (или с другой версией SQL Server) это может быть по-другому.

SQL Server не является процедурным механизмом

Вы не пишете программу, которая выполняется в заданном вами порядке. Вы сообщаете движку, что вы хотели бы получить, и движок находит наилучший способ добиться этого.

Сначала будет выполнен вложенный выбор (вероятно), если его значения необходимы где-то во внешнем запросе. Если внешний запрос допускает значительное сокращение основных строк с заданным фильтром, механизм (вероятно) свяжет дочерние строки как можно позже.

Это зависит от многих обстоятельств, которые вы не можете полностью контролировать.

Что вы могли бы сделать, но на самом деле следует избегать:

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

Но — почти всегда — об этом даже думать не следует. Движок действительно работает довольно эффективно…

Войдите в яркий свет мышления, основанного на множествах!