2010-05-22 45 views
1

我想編寫一個查詢類似以下是否在Oracle中使用select子句中的連接?

select 
    username, 
    (select state from addresses where addresses.username = users.username) email 
from users 

此作品在甲骨文(假設結果從內部查詢是唯一的)。但是,這種寫作風格與查詢有關嗎?

回答

1

本身不是join,而是將子查詢與主要select語句連接起來。

爲了使這是一個連接(這是更快),你需要以下語法:

select users.username as username, addresses.state as email from users 
left join state on (users.username = addresses.username) 

select語句中使用子查詢的總是攜帶DBMS中一個點球。將每個子查詢看作是一個單獨的臨時表,它僅在查詢期間存在於內存中,然後DBMS將其銷燬。首先,它爲主select分配內存,然後爲子查詢表分配更多內存,完成子查詢,然後查看兩個表以整理結果集。

此外,臨時表沒有索引優化,因爲它們是派生表,並且DBMS已被編程爲不花費時間來生成索引(除非DBMS真的很聰明)。

然而,具有join,存儲器僅分配用於主select結果表,並與主結果集填充一次,並加入當joinβed表格中搜索(使用設置爲表中的任何索引,以)。

+0

我會稱之爲相關的子查詢。有趣的轉折是它在這裏的from子句中 - 那麼可能會得到另一個特殊的名字? – Randy 2010-05-23 02:06:51

+0

它在Oracle – 2010-05-23 04:30:02

+1

中稱爲標量子查詢「完整地執行子查詢,然後查看兩個表以整理結果集。」這是不正確的。 Oracle將在主結果集中獲得一行,然後使用用戶名訪問地址表。如果用戶名列在地址中編入索引,則將使用該索引。 – 2010-05-23 04:31:29

1

回到原來的問題,連接是什麼數據庫。如果他們不能很好地融合在一起,他們在市場上就會失敗。所以你會發現這裏討論的任何變化都會很快。

請注意,「用戶」是Oracle中的一個保留字 - 您可能想要調用其他表。另外請注意,如果用戶的地址有多個記錄,則會在原始公式中引發錯誤。普通連接只會給你多行返回。

使用合理的索引我自己的表和數據量,該解釋的計劃是:

原始

SELECT STATEMENT ALL_ROWSCost: 226 Bytes: 390,570 Cardinality: 39,057   
    2 TABLE ACCESS BY INDEX ROWID TABLE X83109.FN_AR_INVOICE Cost: 2 Bytes: 13 Cardinality: 1  
     1 INDEX UNIQUE SCAN INDEX (UNIQUE) X83109.I_FN_AR_INVOICE Cost: 1 Cardinality: 1 
    3 TABLE ACCESS FULL TABLE X83109.FN_AR_LINE_ITEM Cost: 226 Bytes: 390,570 Cardinality: 39,057 

無論是ANSI加入(如上)或傳統的Oracle語法,下面

所示
select users.username as username, addresses.state as email from users, addresses where users.username = addresses.username; 

SELECT STATEMENT ALL_ROWSCost: 377 Bytes: 898,311 Cardinality: 39,057   
    3 HASH JOIN Cost: 377 Bytes: 898,311 Cardinality: 39,057  
     1 TABLE ACCESS FULL TABLE X83109.FN_AR_INVOICE Cost: 149 Bytes: 333,788 Cardinality: 25,676 
     2 TABLE ACCESS FULL TABLE X83109.FN_AR_LINE_ITEM Cost: 226 Bytes: 390,570 Cardinality: 39,057 

所以沒有太大的區別。您應該可以隨意使用連接,但也可以監視性能。

相關問題