服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > 数据库技术 > Oracle技术 > Oracle开发 > 查看文档

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

现象:一条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 |
-----------------------------------------------------

扫描关注微信公众号