嵌套查询与Oracle中的联接

时间:2015-03-05 18:43:21

标签: sql oracle

我知道我们对此有很多疑问,但我的具体针对Oracle。我一直认为使用join更快的性能。但是今天,我有2个返回相同数据的查询,但是一个使用join,一个是嵌套的。解释计划显示嵌套查询的成本更好。我不知道该怎么想。我何时应该使用嵌套查询?何时不应该?我们正在使用Oracle 11.2。

Please see picture

以下是每个解释计划的文字:

select (select p.organization_code from apps.mtl_parameters p where p.organization_id = ship_from_org_id)  
from ont.OE_ORDER_LINES_all l
where header_id = (select header_id from ont.oe_order_headers_all where order_number = '9000385403')
and l.ordered_item = 'SSFRAMES';

PLAN_TABLE_OUTPUT

----------------------------------------------------------------------------------------------
| Id  | Operation                     | Name                    | Rows  | Bytes | Cost (%CPU)|
----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |                         |     1 |    21 |   120   (0)|
|   1 |  TABLE ACCESS BY INDEX ROWID  | MTL_PARAMETERS          |     1 |     8 |     1   (0)|
|   2 |   INDEX UNIQUE SCAN           | MTL_PARAMETERS_U1       |     1 |       |     0   (0)|
|   3 |  TABLE ACCESS BY INDEX ROWID  | OE_ORDER_LINES_ALL      |     1 |    21 |   116   (0)|
|   4 |   INDEX RANGE SCAN            | XXOE_ORDER_LINES_ALL_X6 |   586 |       |     6   (0)|
|   5 |    TABLE ACCESS BY INDEX ROWID| OE_ORDER_HEADERS_ALL    |     1 |    12 |     4   (0)|




select p.organization_code 
from ont.OE_ORDER_LINES_all l
inner join ont.oe_order_headers_all oha on oha.header_id = l.header_id 
inner join apps.mtl_parameters p on p.organization_id = l.ship_from_org_id                
where l.ordered_item = 'SSFRAMES' and oha.order_number = '9000385403'

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------
| Id  | Operation                      | Name                 | Rows  | Bytes | Cost (%CPU)|
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                      |     1 |    41 |   119   (0)|
|   1 |  NESTED LOOPS                  |                      |       |       |            |
|   2 |   NESTED LOOPS                 |                      |     1 |    41 |   119   (0)|
|   3 |    NESTED LOOPS                |                      |     1 |    33 |   118   (0)|
|   4 |     TABLE ACCESS BY INDEX ROWID| OE_ORDER_HEADERS_ALL |     1 |    12 |     4   (0)|
|   5 |      INDEX RANGE SCAN          | OE_ORDER_HEADERS_U2  |     1 |       |     3   (0)|
|   6 |     TABLE ACCESS BY INDEX ROWID| OE_ORDER_LINES_ALL   |     1 |    21 |   114   (0)|
|   7 |      INDEX RANGE SCAN          | OE_ORDER_LINES_N1    |   586 |       |     3   (0)|
|   8 |    INDEX UNIQUE SCAN           | MTL_PARAMETERS_U1    |     1 |       |     0   (0)|
|   9 |   TABLE ACCESS BY INDEX ROWID  | MTL_PARAMETERS       |     1 |     8 |     1   (0)|


select p.organization_code 
from ont.OE_ORDER_LINES_all l
inner join ont.oe_order_headers_all oha on l.header_id in oha.header_id 
inner join apps.mtl_parameters p on p.organization_id in l.ship_from_org_id                
where l.ordered_item = 'SSFRAMES' and oha.order_number = '9000385403';

PLAN_TABLE_OUTPUT

-----------------------------------------------------------------------------------------------
| Id  | Operation                      | Name                    | Rows  | Bytes | Cost (%CPU)|
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                         |     1 |    40 |   115   (0)|
|   1 |  NESTED LOOPS                  |                         |       |       |            |
|   2 |   NESTED LOOPS                 |                         |     1 |    40 |   115   (0)|
|   3 |    NESTED LOOPS                |                         |     1 |    32 |   114   (0)|
|   4 |     TABLE ACCESS BY INDEX ROWID| OE_ORDER_HEADERS_ALL    |     1 |    11 |     4   (0)|
|   5 |      INDEX RANGE SCAN          | OE_ORDER_HEADERS_U2     |     1 |       |     3   (0)|
|   6 |     TABLE ACCESS BY INDEX ROWID| OE_ORDER_LINES_ALL      |     1 |    21 |   110   (0)|
|   7 |      INDEX RANGE SCAN          | XXOE_ORDER_LINES_ALL_X6 |   582 |       |     5   (0)|
|   8 |    INDEX UNIQUE SCAN           | MTL_PARAMETERS_U1       |     1 |       |     0   (0)|
|   9 |   TABLE ACCESS BY INDEX ROWID  | MTL_PARAMETERS          |     1 |     8 |     1   (0)|

1 个答案:

答案 0 :(得分:1)

只是查看解释计划不会给你什么查询实际上更快执行。它仅仅是优化器猜测给出的当前信息。

此外,基数猜测错误往往会传播到更高级别的操作。例如。您在SELECT子句中放置的子选择仅对整个语句计算一次,但当然应该计入每个要返回的预期记录。

最后,相等连接的等价物是IN(...)条件而不是a =(...)条件。