Я заметил нечто неожиданное в том, как SQL Server (в данном случае SQL Server 2008) обрабатывает коррелированные подзапросы в операторе select. Мое предположение заключалось в том, что на план запроса не должен влиять простой порядок, в котором подзапросы (или столбцы, в этом отношении) записываются в предложении projection оператора select. Однако, похоже, это не так.
Рассмотрим следующие два запроса, которые идентичны, за исключением порядка подзапросов в CTE:
--query 1: subquery for Color is second
WITH vw AS
(
SELECT p.[ID],
(SELECT TOP(1) [FirstName] FROM [Preference] WHERE p.ID = ID AND [FirstName] IS NOT NULL ORDER BY [LastModified] DESC) [FirstName],
(SELECT TOP(1) [Color] FROM [Preference] WHERE p.ID = ID AND [Color] IS NOT NULL ORDER BY [LastModified] DESC) [Color]
FROM Person p
)
SELECT ID, Color, FirstName
FROM vw
WHERE Color = 'Gray';
--query 2: subquery for Color is first
WITH vw AS
(
SELECT p.[ID],
(SELECT TOP(1) [Color] FROM [Preference] WHERE p.ID = ID AND [Color] IS NOT NULL ORDER BY [LastModified] DESC) [Color],
(SELECT TOP(1) [FirstName] FROM [Preference] WHERE p.ID = ID AND [FirstName] IS NOT NULL ORDER BY [LastModified] DESC) [FirstName]
FROM Person p
)
SELECT ID, Color, FirstName
FROM vw
WHERE Color = 'Gray';
Если вы посмотрите на два плана запросов, то увидите, что внешнее объединение используется для каждого подзапроса и что порядок соединений совпадает с порядком написания подзапросов. К результату внешнего объединения применяется фильтр для цвета, чтобы отфильтровать строки, в которых цвет не «серый». (Мне странно, что SQL использовал бы внешнее соединение для цветового подзапроса, так как у меня есть ненулевое ограничение на результат цветового подзапроса, но все в порядке.)
Большинство строк удаляются цветным фильтром. В результате запрос 2 значительно дешевле запроса 1, поскольку при втором соединении задействовано меньше строк. Все причины для создания такого утверждения в стороне, это ожидаемое поведение? Разве SQL-сервер не должен перемещать фильтр как можно раньше в плане запроса, независимо от порядка написания подзапросов?
Редактировать: Просто чтобы уточнить, есть веская причина, по которой я изучаю этот сценарий. Возможно, мне понадобится создать представление, которое включает аналогично сконструированные подзапросы, и теперь очевидно, что любая фильтрация на основе этих столбцов, спроецированных из представления, будет отличаться по производительности только из-за упорядочения столбцов!