Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 在Oracle中,在select子句中使用联接是否很慢?_Performance_Oracle - Fatal编程技术网

Performance 在Oracle中,在select子句中使用联接是否很慢?

Performance 在Oracle中,在select子句中使用联接是否很慢?,performance,oracle,Performance,Oracle,我想写一个如下的查询 select username, (select state from addresses where addresses.username = users.username) email from users 假设内部查询的结果是唯一的,则这在Oracle中有效。但是,这种编写查询的方式会带来性能损失吗?这不是连接本身,而是子查询与主select语句的连接 为了使其成为更快的联接,您需要以下语法: select users.username as usern

我想写一个如下的查询

select 
  username, 
  (select state from addresses where addresses.username = users.username) email
from users
假设内部查询的结果是唯一的,则这在Oracle中有效。但是,这种编写查询的方式会带来性能损失吗?

这不是连接本身,而是子查询与主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非常非常聪明


然而,使用联接时,内存仅分配给主选择结果表,并使用主结果集填充一次,并在使用为该表设置的任何索引搜索联接表时添加到内存中。

回到原始问题,联接是数据库所做的事。如果他们做得不好,他们就会在市场上惨败。所以你会发现这里讨论的任何一种变化都会很快

请注意,在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 Join(如上所述)或传统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 

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

我称之为相关子查询。有趣的是,它位于from子句中,因此可能会得到另一个特殊的名称?它在Oracle中称为标量子查询。执行整个子查询,然后查看两个表以整理结果集。这是不正确的。Oracle将在主结果集中获得一行,然后使用用户名访问addresses表。如果用户名列以地址为索引,则将使用该索引。