SQL Server: SELECT * 的真相: 索引覆蓋(index coverage)

SELECT *的效率很糟糕嗎?當然,所有人都知道這一點,但是爲什麼呢?

是因爲返回了太多的數據?

這是一個普遍的回答,但我不這樣認爲。如果你的數據庫設計規範合理,那麼帶寬佔用實際上非常的小。

讓我們看看下面的例子。下面的查詢將會從AdventureWorks.dbo.TransactionHistoryArchive(總共大約有近9萬行數據)中選擇出326行數據。第一個使用了SELECT * 查詢,後一個查詢則有明確的字段。

SELECT * FROM Production.TransactionHistoryArchive 
WHERE ReferenceOrderID < 100

SELECT ReferenceOrderLineID FROM Production.TransactionHistoryArchive 
WHERE ReferenceOrderID < 100

在這種情況下,兩者在網絡帶寬的區別只有15K(180K-165K),大約10%的帶寬差異。的確值得去優化,但不會有很大的效果。

SELECT * 將造成表/索引掃描

SELECT * 的最大問題是將影響查詢計劃。SQL Server主要使用索引去查詢你需要的數據,當索引包括所有的你請求查詢的字段,SQL Server將不需要去在表中查詢。這個概念稱做索引覆蓋。在上面的例子中,第一個查詢結果是在聚集索引掃描中,反過來,第二個例子使用了更多更有效率的索引掃描。在這個案例中,索引掃描比聚集索引掃描快100倍



除非你已經將爲每個字段建立了索引(顯然不是個好主意),SELECT *是不能夠利用到索引覆蓋,你只能去做掃描操作(非常的沒有效率)。

如果你只是查詢你所需要的字段,那你更可能的覆蓋到你的索引。我想這就是不推薦使用SELECT *的主要的原因。

穩定性方面

在維護一個應用程序時,SELECT *也會帶來一些意想不大的問題。它會引起你的代碼發生一些不確定性。如果你增加了一個行(譯註:我覺得這裏應該是字段)到一個表中,那麼SELECT * 返回的結果到你的應用程序中將會在結構上發生變化。良好的應用程序應該是使用字段名稱的,而不應該受此影響。當外界發生變化時,良好的應用程序設計也應該最小化的更改。

英文原稿: http://weblogs.asp.net/jgalloway/archive/2007/07/18/the-real-reason-select-queries-are-bad-index-coverage.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章