一條SQL語句變得巨慢的原因及其解決方法

字號:


    現(xiàn)象:一條SQL突然運(yùn)行的特別慢。
    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,造成連接的順序變化了,原來的驅(qū)動表是uidTable(最多1024條記錄),現(xiàn)在變成了member表做驅(qū)動(600W條)。所以這條語句變的巨慢。
    但是既然是外連接,為什么連接的順序會改變呢?因?yàn)橥膺B接的連接順序不是由COST決定的,而是由連接的條件決定的。發(fā)現(xiàn)執(zhí)行計劃如下:
    -------------------------------------------------------
    | 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 |
    -------------------------------------------------
    為什么根本就沒有執(zhí)行外連接呢?問題出在member.site='test'這個條件上,因?yàn)閷ν膺B接的表加了條件,造成外連接失效。改為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 |