对外连接的表加上条件后将会使外连接失效

王朝other·作者佚名  2008-06-01
窄屏简体版  字體: |||超大  

现象:一条SQL的运行突然变得很慢。

select uidTable.column_value, first_name||' '||last_name,

company, job_title, upper(member_level), upper(service_value)

from (select * from table(select cast(multiset

(select b from bbb)as Taaa) from dual)) uidTable,member

where uidTable.column_value = member.login_id(+) and

member.site='alibaba' and member.site='test';

原因:经检查错误得原因是用户增加了一个条件member.site=test,造成连接的顺序变化了,原来的驱动表是uidTable(最多1024条记录),现在变成了member表做驱动(600W条)。所以这条语句变得特别慢。

但是既然是外连接,为什么连接的顺序会改变呢?因为外连接的连接顺序不是由COST决定的,而是由连接的条件决定的。发现执行计划如下:

-------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost |

------------------------------------------------

| 0 | SELECT STATEMENT | | 1018 | 72278 | 8155 |

| 1 | NESTED LOOPS | | 1018 | 72278 | 8155 |

| 2 | VIEW | | 4072 | 69224 | 11 |

| 3 | COLLECTION ITERATOR SUBQUERY FETCH| | | | |

| 4 | TABLE ACCESS FULL | DUAL | 4072 | | 11 |

| 5 | TABLE ACCESS FULL | BBB | 41 | 287 | 2 |

| 6 | TABLE ACCESS BY INDEX ROWID | MEMBER | 1 | 54 | 2 |

|* 7 | INDEX UNIQUE SCAN | MEMBER_SITE_LID_PK | 4 | | 1 |

-------------------------------------------------

大家要问:“为什么根本就没有执行外连接呢?”问题出在member.site='test'这个条件上,因为对外连接的表加了条件,造成外连接失效。改为member.site(+)='test'后,问题彻底解决。

---------------------------------

| Id | Operation | Name | Rows | Bytes | Cost |

-----------------------------------------------------

| 0 | SELECT STATEMENT | | 1018 | 72278 | 8155 |

| 1 | NESTED LOOPS | | 1018 | 72278 | 8155 |

| 2 | VIEW | | 4072 | 69224 | 11 |

| 3 | COLLECTION ITERATOR SUBQUERY FETCH| | | | |

| 4 | TABLE ACCESS FULL | DUAL | 4072 | | 11 |

| 5 | TABLE ACCESS FULL | BBB | 41 | 287 | 2 |

| 6 | TABLE ACCESS BY INDEX ROWID | MEMBER | 1 | 54 | 2 |

|* 7 | INDEX UNIQUE SCAN | MEMBER_SITE_LID_PK | 4 | | 1 |

-----------------------------------------------------

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航