2009-10-21 67 views
1

我有以下查詢從交易表和交易明細獲取交易。這兩個表都有大量條目,所以此查詢需要一段時間才能返回結果。避免全表掃描

SELECT * FROM transactions t LEFT JOIN transac_detail tidts ON (tidts.id_transac = t.id); 

不過,我因爲事實上,甲骨文執行全表掃描兩個表,根據解釋計劃,即使t.id和tidts.id_transac有索引,更擔心。

有什麼辦法可以在不觸及表結構的情況下優化它嗎?

+0

Oracle做什麼?散列連接?哈希聯接非常快,通常比使用索引的執行計劃更快。向我們展示您的解釋計劃並檢查統計數據是否準確。 – tuinstoel 2009-10-21 18:48:43

回答

4

我不認爲這是真的,SQL必須最好與全表掃描服務。在兩者之間存在外鍵的情況下,這確實是最明顯的事實,但即使如此,也可能有例外。

我認爲關鍵的問題是這樣的:「每個表中的行的比例應該包含在結果集中?」。如果答案是「100%來自每個」,那麼你就有了全表掃描(和散列連接)的清晰情況。

但是考慮一下情況,即表A和表B連接在一起,表A包含5行,並且包含100行的表B(父)的外鍵包含一行。很明顯,在這裏你需要用B的嵌套循環連接來查找A的完整掃描(表B中的連接列將被索引,因爲它必須是主鍵或唯一鍵)。

在OP的情況下,雖然看起來你會期望從每個表中返回100%的行。我期望看到對這兩個表的完整掃描,並且首先訪問帶有TRANSACTIONS(可能是較小的表)的散列連接並將其構建到散列表中。這將是最佳的連接方法,我只是在尋找一種情況,即單次散列連接的TRANSACTIONS太大。如果連接溢出到磁盤上,那麼這可能是一個性能問題,您必須考慮增加內存分配或等分兩個表以減少內存需求。

+0

非常全面的答案,一如既往。 +1 – 2009-10-21 16:32:21

0

全表掃描不一定是壞的 - 它似乎並不是以任何方式限制結果集,這可能是執行查詢的最有效方式。您始終可以通過使用索引提示並確定結果的性能更改來驗證此情況。

2

由於給定的查詢返回所有內容,全表掃描實際上可能是達到最終結果的最快方式。由於I/O與CPU時間相比非常昂貴,因此將所有內容拉入內存並進行最終連接可能更有效,而不是在一個表中循環查找索引。

要確定查詢是否可能實際上跑得更快,你可以試試下面的方法:

  • 看看查詢計劃僅在數據的子集(例如,一系列的id的)
  • 嘗試查詢上大小不等的子集,看到你在這裏密謀什麼樣的曲線
0

您沒有一個WHERE子句,因此甲骨文認爲,因爲它必須從兩個表返回所有記錄全表掃描將是最有效的。

如果您要添加一個使用索引的WHERE子句,我想您會發現EXPLAIN PLAN將不再使用全表掃描。