【茶包射手筆記】在 View 使用 SELECT * 的風險

分享同事踩到的 SELECT * 地雷一枚。

大家應該在程式設計準則都看過這條-「避免使用 SELECT * FROM Table,應以 SELECT Col1, Col2… 明確列舉欄位…」。

如此建議必有其考量:第一個理由顯而易見,正向表列必要欄位,可避免在網路傳送用不到的資料浪費頻寬,並能減少客戶端、伺服器端處理多餘資料的資源損耗。再者,查詢欄位多寡也可能影響效能,SELECT * 時為牽就非必要欄位,資料庫可能改用較無效率的索引,不利效能最佳化。還有一種極端情境,若所需欄位都存在於 Non-Clustered Index,即便使用的索引相同,SELECT * 迫使資料庫逐筆再 Key Lookup 取回完整資料列,拖累執行計劃並衍生非必要 IO。

另外,未正向列舉欄位在 Schema 變動時容易造成問題。例如:INSERT INTO TableA SELECT * FROM TableB,一旦 TableA 或 TableB 欄位增減或調換順序就會出錯。應寫成 INSERT INTO TableA (C1,C2,C3) SELECT C1,C2,C3 FROM TableB 才嚴謹。

以上均為我已知效能問題或嚴謹性疏失,但這次的案例讓我有些意外,是一個 View 使用 SELECT * 導致 Schema 一變更就爆炸的個案!

使用以下案例重現問題:

有一個具備 ID、NAME 兩個欄位的資料表 TBL9527,另外有 View VW9527,內容為 SELECT * FROM TBL9527。塞入一筆資料並查詢 VW9527,結果符合預期:

修改 TBL9527,在 ID 與 NAME 欄位間插入一個 TEAM 欄位。

猜猜怎麼了?SELECT * FROM TBL9527 結果正常,但 VW9527 查詢結果的 NAME 對應成 TEAM,内容為 NULL!

要修正問題,需執行 EXEC sp_RefreshView 'VW9527' 更新 View 的 Metadata。

咦~ 在 View 使用 SELECT * 的朋友愛自意哦!

【參考資料】

歡迎推文分享:
Published 15 February 2017 10:26 PM 由 Jeffrey
Filed under:
Views: 7,851



意見

# ace said on 17 February, 2017 03:59 AM

多加一個欄位頂多是沒有select出來,更新view之後就正常了,再把這個多的欄位砍掉後,再執行這個view會發現出錯 XD

一樣的問題,似乎SQL server 有去記錄這個view需要select出哪些欄位

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<February 2017>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
2627281234
567891011
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication