對於「檢視表」,我一直有種「用它是否有錯」的感覺,因為它的優點雖然是「方便我們在寫 SQL 查詢式時,不需要寫一大串 JOIN 的資料表,只要將它們組合成一個檢視表即可」!但問題是,將檢視表用在程式中的SQL查詢式時,例如:
SELECT xxx,ooo FROM View1 WHERE v_date BETWEEN '2013/6/1' AND '2013/6/2'
看起來,雖然有經過WHERE條件的篩選,但是,它是不是「其實是先經過了一個"完全沒有篩選"的"子查詢"」,然後取回了「全部的資料」再給「WHERE」來篩出範圍內的資料呢?
如果原理真的是這樣,那檢視表不是應該少用為妙嗎???......因為一用它就會產生效能問題?
利用 AdventrueWork 的 SalesOrderHeader 模擬原 PO 所說的簡易範例
- 情況 1:直接搜尋 SalesOrderHeader
SELECT * FROM [Sales].[SalesOrderHeader] WHERE SalesOrderID = 70309
- 情況 2:衍伸資料表
SELECT T.*
FROM
(
SELECT * FROM [Sales].[SalesOrderHeader]
) AS T
WHERE T.SalesOrderID = 70309
- 情況 3:直接對 View 下條件
CREATE VIEW vwSalesOrderHeader
AS
SELECT * FROM [Sales].[SalesOrderHeader]
GO
SELECT * FROM vwSalesOrderHeader WHERE SalesOrderID = 70309
上述三種情況的執行計畫皆相同,情況 2 和情況 3 並不會先把全部資料都抓出來後,再篩選資料。
SQL Server 是 Costly-base 而不是 Rule-base,Query Optimizer 會根據傳入的 T-SQL 語法,選擇 "最低成本執行計畫" 來執行,使用者假如只是根據 T-SQL 語法邏輯順序來判斷效能議題,較不具意義
- 延伸閱讀
- [SQL] T-SQL 語法邏輯順序
- 參考資料
- 論壇問題出處
- 論壇討論 - SP VS View
- T-SQL Anti-Patterns: Nested Views
- FB 討論
- PTT 討論
沒有留言:
張貼留言