2008-10-16 39 views
23

我使用MS SQL Server 2005中是否有差異,給SQL引擎,有*選擇之間的差異,選擇[列表中的每個山坳]

SELECT * FROM MyTable; 

SELECT ColA, ColB, ColC FROM MyTable; 
之間

當ColA,ColB和ColC代表表格中的每一列時?

如果他們是一樣的,是否有一個原因爲什麼你應該使用第二個呢?我有一個在LINQ上很沉重的項目,我不確定它生成的標準SELECT *是一種不好的做法,或者如果我總是在其上選擇一個.Select()來指定我想要的列。

編輯:改變「當ColA,ColB和ColC都是表格的列?」到「當ColA,ColB和ColC代表表格中的每一列?」爲清楚起見。

+1

另請參見:http://stackoverflow.com/questions/65512/which-is-faster-best-select-or-select-column1-colum2-column3-etc – 2009-08-12 12:46:27

回答

38

一般來說,最好是明確的,所以Select col1, col2 from Table更好。原因是在某些時候,可能會向該表中添加額外的列,並且會導致不需要的數據從查詢中返回。

雖然這不是一條硬性規則。

+2

在許多情況下,它也會導致依賴代碼打破。對於懶惰開發人員在INSERT語句中不使用列列表的環境尤其如此。 – 2008-10-16 15:18:18

+3

但在某些情況下,顯式意味着您可能不得不更改每個使用該表的代碼,因爲您希望新列幾乎在任何地方都顯示出來。儘管您經常需要更改視圖代碼,但在這些情況下,僅使用`*`進行操作仍然會將工作量減半。這一切都取決於你在做什麼,以及你對未來的計劃是什麼。 – 2011-03-21 17:00:09

4

當您單獨選擇每個字段時,更清楚哪些字段實際上被選中。

17

1)第二個更明確地指出返回哪些列。那麼第二個的價值就是你明確知道哪些列回來了。

2)當列數多於明確使用的列數時,這涉及潛在的更少數據返回。

3)如果您通過添加新列來更改表,則第一個查詢會更改,第二個查詢不會更改。如果你有代碼,如「所有列返回做...」,那麼結果會改變,如果你使用第一個,但不是第二個。

4

一些原因不使用的第一條語句(SELECT *)是:

  1. 如果你添加一些大油田(BLOB列將非常壞的)後來到該表,你可以吃虧在應用
  2. 性能問題如果查詢是加入查詢兩個或多個表,某些字段可能有同名。最好保證你的字段名稱不同。
  3. 查詢的目的是第二條語句更清晰的從編程美學觀點
8

您應該指定明確的列的列表。 SELECT *會帶來更多的列,而您需要創建更多的IO和網絡流量,但更重要的是,即使存在非聚集覆蓋索引(在SQL Server上),也可能需要額外的查找。

+0

是的!這是明確的最好理由 - 涵蓋索引。 – 2008-10-16 15:11:05

+0

接受的答案似乎滿足了更多人對[*]和col1,col2,col3之間差異的[錯誤]概念。 – ProfK 2010-01-02 23:05:02

1

快速查看查詢執行計劃表明查詢是相同的。

一般的經驗法則是,你會希望限制你的查詢只有你需要返回的字段。

2

它對前向兼容性很好。

當您使用

SELECT * FROM myTable 

和 「mytable的」 3列。你得到同樣的結果

SELECT Column1, Column2, Column3 FROM myTable 

但是,如果你在將來添加新列,你會得到一個diferent結果。

當然,如果您更改現有列的名稱之一,第一種情況下會得到結果,第二種情況下會出現錯誤(我認爲這是應用程序的正確行爲)。

+1

我不確定發生未來更改時的中斷是否是前向兼容性的定義。 – 2008-10-16 15:11:35

+0

我認爲TcKs的情況是,打破比假裝工作(但不工作)更好。 – 2008-10-16 15:15:21

1

對於LinqToSql,如果您打算稍後修改這些記錄,則應將整個記錄拉入內存。

3

SELECT *在大多數地方都是不好的做法。

  • 如果有人向該表中添加2GB的BLOB列會怎麼樣?
  • 什麼是某人真的添加了該列的任何列?

這是一個等待發生的錯誤。

1

這取決於你的意思是「差異」。有明顯的語法差異,但真正的差異是性能。

當你說SELECT * FROM MyTable,你說的是SQL查詢引擎返回與從該表中的列的所有數據集,而SELECT ColA, ColB, ColC FROM MyTable告訴查詢引擎與可樂,COLB返回一個數據集,和ColC從表中。

假設你有一個100列的表定義爲CHAR [10]。 SELECT *將返回100列* 10字節價值的數據,而SELECT ColA, ColB, ColC將返回3列* 10字節價值的數據。這是通過線路傳回的數據量的巨大差異。

指定列列表還會讓您更感興趣的是哪些列。缺點是,如果您從表中添加/刪除列,則需要確保列列表已更新,但我認爲與性能增益相比,這是一個很小的價格。

0

選擇每一列比*更好,因爲如果您添加或刪除新行,您必須查看代碼並查看您對檢索數據所做的操作。
此外,它可以幫助你更好地理解你的代碼,並允許你使用別名作爲列名(如果你正在執行一個表共享一個名字列的表)

9

我會得到很多的人對我感到不滿,但特別是如果我稍後添加列時,我通常喜歡使用SELECT * FROM表。由於這個原因,我被稱爲懶惰,因爲如果我對錶進行任何修改,我不想追蹤所有使用該表的存儲過程,只需在應用程序的數據訪問層類中進行更改。在某些情況下,我將指定列,但在我試圖從數據庫中獲取完整「對象」的情況下,我寧願只使用「*」。而且,是的,我知道有人會因此而恨我,但它讓我在向我的應用程序添加字段時更快,更無缺陷。

2

如果您的代碼依賴於特定順序的某些列,則需要列出列。如果不是,如果您使用「*」或在select語句中寫入列名稱,它並沒有真正的區別。

一個例子是如果你在表格中插入一列。

拿這個表: 可樂COLB COLC

你可能有一個查詢:

SELECT * 
FROM myTable 

然後代碼可能是:

rs = executeSql("SELECT * FROM myTable") 
while (rs.read()) 
    Print "Col A" + rs[0] 
    Print "Col B" + rs[1] 
    Print "Col C" + rs[2] 

如果COLB之間增加一列ColC,查詢不會返回您要查找的內容。

1
SELECT * FROM MyTable 

select *取決於模式中的列順序,所以如果您引用由集合的索引#設置的結果,您將查看錯誤的列。

SELECT Col1,Col2,Col3 FROM MyTable 

這個查詢會給你一個隨時間保持不變的集合,但你多久更改一次列順序呢?

3

有兩件事情:

  • 的人相當數量已經張貼在這裏建議不要使用*,並給出了幾個很好的理由,這些問題的答案。在迄今爲止的其他10個回覆中,只有一個不建議列出列。
  • 在發佈幫助網站(如StackOverflow)時,人們通常會對該規則做出例外規定,因爲他們通常不知道表中的列是什麼或對您的查詢很重要。出於這個原因,你會在這裏和網上其他地方看到很多使用*語法的代碼,即使海報會在他自己的代碼中避免它。
9

問題的雙方是這樣的:顯式列規範在添加新列時會提供更好的性能,但*規範在添加新列時不需要維護。

要使用哪個取決於您希望添加到表中的列的類型以及查詢的要點。

如果您使用表作爲對象的後備存儲(這似乎可能在LINQ-to-SQL的情況下),您可能希望將任何新列添加到此表中以包含在您的對象中, -versa。你正在平行維護它們。因此,對於這種情況,SELECT子句中的*規範是正確的。明確的規範會在每次更改時爲您提供額外的維護,並且如果您沒有正確更新字段列表,則會出現錯誤。

如果查詢要返回很多記錄,那麼爲了性能原因,最好使用明確的規範。

如果兩個事情都是真的,請考慮有兩個不同的查詢。

0

一個例子,爲什麼你永遠不會(imho)應該使用SELECT *。這不涉及MSSQL,而是MySQL。 5.0.12之前的版本以非標準方式返回某些類型連接的列。當然,如果你的查詢定義了你想要的列和你沒有問題的順序。想象一下如果他們不這樣做的樂趣。

(一個可能的例外:您的查詢只從一個表選擇和你的名字,而不是位置標識列選擇的編程語言。)

0

使用「SELECT *」爲程序員打字優化。而已。這是唯一的優勢。

相關問題