這實際上取決於你的表設置。除非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
的IO現在變成:
Table '#tblStudentPrefixes'. Scan count 1, logical reads 1
Table '#tblStudents'. Scan count 1, logical reads 142
不過,我想STILL R ecommend切換到交叉連接的位置:
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;
的執行計劃檢驗示出了使用表線軸,其是一個單值非常不必要子選擇:
![enter image description here](https://i.stack.imgur.com/RU4nH.png)
所以在總結,它取決於你的表設置是否會爲每行執行,但不管你是否給予優化器一個更好的機會,如果你切換到交叉連接。
編輯
在你需要從tblstudent
返回行的時候沒有匹配的tblStudentPrefixes
SeniorPrefix
事實輕,而且PrefixName
不currenty constrianed是唯一的,則最好解決方法是:
SELECT *,
(SELECT MAX(value) FROM #tblStudentPrefixes WHERE PrefixName = 'SeniorPrefix')
AS StudentPrefix
FROM #tblStudents;
如果您確實將其限制爲唯一,那麼以下3個查詢會生成(essentiall Y)相同的計劃和相同的結果,它只是個人喜好:
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是獨一無二的,你可以把它改寫作爲外連接 – 2014-10-22 09:22:53