Это на самом деле зависит от вашей таблицы, созданной. Если prefixName
не может быть уникальным, вы можете столкнуться с ошибками, когда подзапрос возвращает более одной строки. Если он не ограничен уникальным, но, оказывается, уникален для SeniorPrefix
, тогда ваш запрос будет выполнен 1000 раз. Для демонстрации я использовал следующий DDL:
CREATE TABLE #tblStudents (ID INT IDENTITY(1, 1), Filler CHAR(100));
INSERT #tblStudents (Filler)
SELECT TOP 10000 NULL
FROM sys.all_objects a, sys.all_objects b;
CREATE TABLE #tblStudentPrefixes (Value VARCHAR(10), PrefixName VARCHAR(20));
INSERT #tblStudentPrefixes (Value, PrefixName) VALUES ('A Value', 'SeniorPrefix');
Запуск ваш запрос дает следующий вывод IO:
Table '#tblStudentPrefixes'. Scan count 10000, logical reads 10000
Table '#tblStudents'. Scan count 1, logical reads 142
Ключ является 1000 логических чтений на tblStudentPrefixes. Другая проблема с этим не будучи стесненным быть уникальным в том, что если у вас есть дублирует ваш запрос будет завершаться с ошибкой:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Если вы не можете сдержать PrefixName
быть уникальными, то вы можете остановить его выполнение для каждая строка и избежать ошибок при использовании TOP
:
SELECT *,
(SELECT TOP 1 value FROM #tblStudentPrefixes WHERE PrefixName = 'SeniorPrefix' ORDER BY Value)
AS StudentPrefix
FROM #tblStudents
НЛ теперь становится:
Table '#tblStudentPrefixes'. Scan count 1, logical reads 1
Table '#tblStudents'. Scan count 1, logical reads 142
Тем не менее, я бы до сих пор г ecommend переключение на CROSS JOIN здесь:
SELECT s.*, p.Value AS StudentPrefix
FROM #tblStudents AS s
CROSS JOIN
( SELECT TOP 1 value
FROM #tblStudentPrefixes
WHERE PrefixName = 'SeniorPrefix'
ORDER BY Value
) AS p;
Проверка планов выполнения показывает, что суб-выбор с помощью таблицы золотник, который является очень необходимым для одного значения:
Таким образом, в резюме, это зависит от вашей таблицы, будет ли она выполняться для каждой строки, но независимо от того, что вы даете оптимизатору больше шансов, если вы переключитесь на перекрестное соединение.
EDIT
В свете того факта, что вам нужно возвращать строки из tblstudent
, когда нет матча за SeniorPrefix
в tblStudentPrefixes
, и что PrefixName
не CurrentY constrianed быть уникальным, то лучшим решение:
SELECT *,
(SELECT MAX(value) FROM #tblStudentPrefixes WHERE PrefixName = 'SeniorPrefix')
AS StudentPrefix
FROM #tblStudents;
Если ограничить его уникальным, то следующие 3 запросов производства (essentiall у) тот же план и те же результаты, это просто личные предпочтения:
SELECT *,
(SELECT value FROM #tblStudentPrefixes WHERE PrefixName = 'SeniorPrefix')
AS StudentPrefix
FROM #tblStudents;
SELECT s.*, p.Value AS StudentPrefix
FROM #tblStudents AS s
LEFT JOIN #tblStudentPrefixes AS p
ON p.PrefixName = 'SeniorPrefix';
SELECT s.*, p.Value AS StudentPrefix
FROM #tblStudents AS s
OUTER APPLY
( SELECT Value
FROM #tblStudentPrefixes
WHERE PrefixName = 'SeniorPrefix'
) AS p;
если вы PrefixName уникален, вы можете переписать его как внешнее соединение –