2010-05-22 50 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 

所以没有太大的区别。您应该可以随意使用连接,但也可以监视性能。

相关问题