2017-10-11 98 views
0

我有一個接一個地運行多個SQL查詢來獲取一組數據。在每個查詢中,都有一些加入的表與其他查詢完全相同。例如:我以前的SQL查詢會影響我當前的查詢嗎?

查詢1

SELECT * FROM 
Product1TableA A1 
INNER JOIN Product1TableB B on A1.BId = B.Id 
INNER JOIN CommonTable1 C on C.Id = B.CId 
INNER JOIN CommonTable2 D on D.Id = B.DId 
... 

QUERY2

SELECT * FROM Product2TableA A2 
INNER JOIN Product2TableB B on A2.BId = B.Id 
INNER JOIN CommonTable1 C on C.Id = B.CId 
INNER JOIN CommonTable2 D on D.Id = B.DId 
... 

我玩了重新排序的連接(每個查詢各地加盟2十幾桌),我讀到這裏,他們應該不會真正影響查詢執行,除非SQL在優化過程中因爲查詢有多大而「放棄」...

我想知道的是if聚成一團常見的表連接在我所有的問題實際上幫助的開始......

+3

我不明白你的問題是什麼。 –

+1

除非您正在更新表結構或修改表中的數據,否則1個查詢不應該「影響」針對該表的後續查詢。 – tommyO

+0

此外,SQL Server的版本是相關的,因爲舊版本比新版本更適合JOIN排序。請編輯您的問題並添加適當的標籤。 (SQL服務器-XXXX)。 – Alexei

回答

1

我想我明白他想說/做到:

我想知道如果聚成一團公共表在開始我的所有查詢的 實際上有助於聯接是...

試想一下,你有一些查詢和每個查詢已超過3內連接。查詢是不同的,但總是有(例如)共同的3個表被加入相同的領域。現在的問題是: 如果每個查詢都以連接中的這3個表開始,並且所有其他表在連接後會發生什麼?

答案是它會改變什麼,即優化器將重新安排它認爲會帶來最佳的執行方式的表。

事情可能會改變,如果,例如,您保存這些3的結果加入到一個臨時表中,然後使用這個保存的結果與其他表加入。但這取決於您的查詢使用的過濾器。如果您有適當的索引並且您的查詢過濾器足夠有選擇性(以便您的查詢返回非常少的行),則無需緩存具有太多行的中間無過濾結果,因爲優化器可以選擇首先過濾每個表,加入他們

+0

「答案是什麼都不會改變」< - 謝謝!所以沒有更多理由進一步「改善」當前查詢。我已經能夠清理它,我想知道是否還有更多的改進空間。 – Oyen

2

從理論上講,join S的from子句中的順序不作對查詢性能的差異。對於少數表格,應該沒有區別。優化器應該找到最佳的執行路徑。

對於大量的表格,優化程序可能必須短路搜索關於join的訂單。然後它會使用啓發式 - 這些可能會受到join訂單的影響。

以前的查詢不會影響特定的執行計劃。

如果您遇到性能問題,我猜join順序不是根本原因。我在SQL Server中遇到的最常見的問題是不適當的嵌套循環連接 - 並且可以使用優化器提示來處理這些問題。

+0

謝謝!所以我猜想當加入2打表格時,儘管「先前的查詢對特定的執行計劃沒有影響」,但我如何訂購我的連接並不重要。 – Oyen

1

戈登的回答是一個很好的解釋,但this answer解釋JOIN的行爲,並指定SQL Server的版本是相關的:

雖然加入順序在優化改變,優化器 簡化版,嘗試所有可能的連接命令。當它發現 認爲可行的解決方案時它會停止,因爲優化的行爲使用了寶貴的資源 。

儘管優化器盡力爲JOIN選擇好順序,但由於有許多JOIN會產生更大的獲得不太好計劃的機會。

就我個人而言,我在ERP中的某些視圖中看到了許多JOIN,並且他們通常運行正常。但是,有時候(根據客戶端的數據量,實例配置等),這些視圖中的一些選擇比預期的要多得多。

如果此數據到達實際應用程序(.NET,JAVA等),一種方法是緩存來自所有小表的信息,將其存儲爲字典(哈希)並根據鍵執行O(1)查找。

這提供了減少JOIN計數並且不從這些表的數據庫執行讀取(除了在緩存數據時一次)的優點。但是,這增加了應用程序的複雜性(緩存管理)。

另一種解決方案是使用臨時表並填充他們多次查詢,以避免每一個查詢很多連接。此解決方案通常執行得更好,同時也增加了可調試性(如果查詢不提供正確的數據或根本沒有數據,則10-15個JOIN中哪個是問題?)。

所以,我的回答你的問題是:你可能會從重新排序JOIN子句得到一些好處,但我建議避免大量的擺在首位聯接。

相關問題