| 導購 | 订阅 | 在线投稿
分享
 
 
 

對外連接的表加上條件後將會使外連接失效

來源:互聯網  2008-06-01 02:12:10  評論

現象:一條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 |

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

現象:一條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- 王朝網路 版權所有