Oracle SQL使用IN子句连接表需要很长时间

时间:2016-01-28 02:32:41

标签: oracle join oracle11g

我有两个查询需要为了商业目的而加入,以使其成为一步过程

SELECT
  empid,
  assest_x_id,
  asset_y_id
FROM emp e
WHERE e.empid = 'SOME_UNIQUE_VAL';

结果:

EMPID    ASSEST_X_ID   ASSET_Y_ID
=======  ============  =========== 
1234         abc           pqr

- 即使表格中有数百万行,这将在毫秒内返回1行,因为它使用具有唯一值的PK列。

现在在另一个DB当前市场价格中有另一个资产评估表 (也是一百万行)

SELECT
  asset_id,
  assest_type,
  asset_current_price
FROM asset_values@x_db a
WHERE (asset_id, assest_type) IN (('abc', 'X'), ('pqr', 'Y'));

结果:

asset_id    asset_type assest_current_price
========    =========  =============
abc         X          10000    
pqr         Y          5000

这也会在几毫秒内返回2-3行,因为为asset_id,asset_type值的组合定义了主键,并且只有3种类型的资产为X / Y / Z. (注意:无法在业务规则中将此表进一步规范化)

**现在要在脚本中进行一步过程查询,我尝试加入这些查询,这些查询可以从用户那里获取并获得所有想要的结果。

但现在的问题是,当我尝试在单个查询中合并这两个时,如下面运行15分钟以给出结果**

SELECT
  a.asset_id,
  a.asset_type,
  asset_current_price
FROM asset_values@x_db a, emp b
WHERE b.empid = 'SAME_UNIQUE_VAL'
      AND (asset_id, asset_type) IN ((b.asset_x_id, 'X'), (b.asset_y_id, 'Y'));

令人惊讶的解释计划也很好。 (字节:597成本:2) 有人可以就此提出专家意见吗?

SELECT STATEMENT  ALL_ROWSCost: 6  Bytes: 690  Cardinality: 2                   
    13 CONCATENATION                
        6 NESTED LOOPS  Cost: 3  Bytes: 345  Cardinality: 1             
            3 PARTITION RANGE SINGLE  Cost: 1  Bytes: 2,232  Cardinality: 9  Partition #: 3  Partitions accessed #1     
                2 TABLE ACCESS BY LOCAL INDEX ROWID TABLE MYPRDAOWN.EMP Object Instance: 2  Cost: 1  Bytes: 2,232  Cardinality: 9  Partition #: 4  Partitions accessed #1   
                    1 INDEX RANGE SCAN INDEX MYPRDAOWN.EMP_7IX Cost: 1  Cardinality: 9  Partition #: 5  Partitions accessed #1
            5 FILTER  Cost: 1  Bytes: 97  Cardinality: 1        
                4 REMOTE REMOTE SERIAL_FROM_REMOTE ASSEST_VALUES XDB    
        12 NESTED LOOPS  Cost: 3  Bytes: 345  Cardinality: 1            
            9 PARTITION RANGE SINGLE  Cost: 1  Bytes: 2,232  Cardinality: 9  Partition #: 9  Partitions accessed #1     
                8 TABLE ACCESS BY LOCAL INDEX ROWID TABLE MYPRDAOWN.EMP Object Instance: 2  Cost: 1  Bytes: 2,232  Cardinality: 9  Partition #: 10  Partitions accessed #1  
                    7 INDEX RANGE SCAN INDEX MYPRDAOWN.EMP_7IX Cost: 1  Cardinality: 9  Partition #: 11  Partitions accessed #1
            11 FILTER  Cost: 1  Bytes: 97  Cardinality: 1       
                10 REMOTE REMOTE SERIAL_FROM_REMOTE ASSEST_VALUES XDB   

1 个答案:

答案 0 :(得分:0)

来自http://docs.oracle.com/cd/B28359_01/server.111/b28274/optimops.htm#i49732

  

当连接小的数据子集并且连接条件是访问第二个表的有效方式时,嵌套循环连接很有用。

使用散列连接:

  

...用于连接大型数据集。优化器使用两个表或数据源中较小的一个来在内存中的连接键上构建哈希表。然后它扫描较大的表,探测哈希表以找到连接的行。

实现它使用提示

SELECT /*+ use_hash(a,b) */ a.asset_id,
  a.asset_type,
  asset_current_price
FROM asset_values@x_db a,
  emp b
WHERE b.empid               = 'SAME_UNIQUE_VAL'
AND (asset_id, asset_type) IN ((b.asset_x_id, 'X'), (b.asset_y_id, 'Y'));