2011-03-31 46 views
6

我有一個包含大量數據的表,我需要將它與其他一些大表連接起來。SQL - 使用連接過濾大表 - 最佳實踐

我的桌子的一小部分實際上每次都與我相關。

何時最好過濾我的數據?

  1. 在SQL的where子句中。

  2. 用特定數據創建一個臨時表,然後加入它。

  3. 將謂詞添加到第一個內部聯接ON子句。

  4. 一些其他的想法。

1.

Select * 
From RealyBigTable 
Inner Join AnotherBigTable On … 
Inner Join YetAnotherBigTable On … 
Where RealyBigTable.Type = ? 

2.

Select * 
Into #temp 
From RealyBigTable 
Where RealyBigTable.Type = ? 

Select * 
From #temp 
Inner Join AnotherBigTable On … 
Inner Join YetAnotherBigTable On … 

3.

Select * 
From RealyBigTable 
Inner Join AnotherBigTable On RealyBigTable.type = ? And … 
Inner Join YetAnotherBigTable On … 

另一個問題: 首先會發生什麼? JoinWhere

回答

11

因爲您正在使用INNER JOINs WHERE或JOIN辯論只取決於您的品味和風格。就我個人而言,我喜歡在ON子句中保留兩個表之間的鏈接(例如外鍵約束),並在WHERE子句中保留實際的數據過濾器。

SQL Server會將查詢解析到同一個記號樹中,因此會構建相同的查詢執行計劃。

如果您使用的是[LEFT/RIGHT] OUTER JOINS,它會帶來一個不同的世界,因爲不僅性能可能不同,而且結果也很可能。


要回答您的其他問題:

什麼時候最好過濾我的數據?

  1. 在SQL的where子句中。
  2. 用特定的數據創建一個臨時表,然後加入它。
  3. 將謂詞添加到第一個內部聯接ON子句。
  4. 一些其他的想法。

在WHERE或ON子句中,兩者都被視爲相同。對於3,「第一個內連接」沒有關聯。在多表INNER JOIN場景中,查詢優化器會按照它認爲合適的順序對其進行洗牌,這首先(在查詢中)並不重要。

使用臨時表是完全沒有必要的,也無濟於事,因爲無論如何您都必須提取相關部分 - 這也是JOIN所要做的。此外,如果您在JOIN條件/ WHERE過濾器上有良好的索引,則索引將僅用於訪問相關數據,而不會查看其餘表格。

+1

確定。但是將數據放在臨時表中並且只有(內部)連接不同的表才更好? – 2011-03-31 08:34:42

+0

@gil - 請參閱編輯答案 – RichardTheKiwi 2011-03-31 08:41:23

1

您應該將您的查詢放入管理工作室,勾選「包含實際執行計劃」並運行它。這樣你就可以得到確切答案,SQL服務器用你的查詢做了什麼。從那時起,您可以繼續優化。

一般:

  • 用於聯接的列應該被索引
  • 用最挑剔的過濾器第一
0

在一個體面的基於成本的查詢規劃發生的事情是(你的情況)

  1. 連接條件和條件在同一層解析的地方

  2. 加入和統計數據的類型確定的路徑(第一發生什麼) - 中,最小的中間結果被檢索這樣的方式(至少I/O>最快的查詢)