2012-12-11 88 views
2

有雙向做多表查詢:問題關於多表查詢性能

查詢1:

select t1.a, t2.b from t1, t2 where t1.a = t2.a 

查詢2:

每一行:

select t1.a from t1 

d o另一個查詢:

select t2.b from t2 where t2.a = '??' 

當表格非常大時,哪一個表現更好?

+2

執行1次查詢是比執行許多更快。如果沒有,那麼你需要添加索引到你的表中。 –

+0

查詢2是什麼?這是一個子選擇,還是你打算使用遊標循環'每行'? – mipe34

+0

如果您唯一的考慮因素是在數據庫上運行的一個查詢,那麼第一個查詢會運行得更快,但是,如果這是一個多用戶環境,並且該表非常大,那麼當第一個查詢運行得更快時,它可能會導致更長的鎖定,與其他用戶的死鎖,您將需要確保指定相關的表提示來管理鎖。 – GarethD

回答

1

您應該始終讓DBMS儘可能在單個查詢中完成儘可能多的工作。

DBMS知道每個數據庫中有多少個元組,並且有一種方法來估計結果將具有的元組數量。現代DBMS具有非常複雜的算法,負責找到執行任何查詢(規劃器)的最有效方法。除非你知道你在做什麼,爲什麼你在做(即你知道你的算法會比DBMS運行得更快,更重要的是,爲什麼),你應該讓DMBS完成它的工作。

回答你的問題更準確地說:

您的查詢#1可以與答案不同的方法,這取決於表的大小。讓我們假設這兩者都是巨大的。要解決的一個方法是使用基於排序的連接:基於連接屬性對兩個表進行排序,然後合併它們。這基本上相當於在每個表上進行合併排序所花費的時間。每張表的每頁將被讀取和寫入幾次(取決於您在DMBS中有多少緩衝空間)。因此,T1和T2中的每個元組都會被讀取/寫入,比如十幾次。

如果我們實現你的方法,將會有與T1大小的元組一樣多的查詢。讓我們假設T2沒有索引,因此查詢將讀取T2 T1時間內的每個元組。

如果你有一個在T2上的索引,你可以期望爲T1中的每個元組讀一些頁面。因此,查詢的代價是讀取T1的開銷,然後對於T1中的每個元組,需要讀取幾頁(2-5)才能找到T2中的匹配元組。

如果T1非常小,T2非常大,則查詢2會更快!但是,數據庫管理系統會發現,並會執行你的算法來回答Q1(它被稱爲基於循環的連接)。此外,發送給DBMS的每個查詢都需要時間來處理(方法1沒有的開銷)。

這是一種常見的幼稚DBMS程序員的失誤:讓DB做了一點工作,那麼每一個元組,做更多的工作。

相反,您應該考慮讓數據庫管理系統在儘可能少的查詢中完成所有處理。它會在業績中得到回報。

最後,如果您真的對性能感興趣,請獲取您最喜愛的DMBS的文檔,並閱讀它如何進行查詢評估以及如何改進它。

--dmg