【丹臣】優化SQL的另類思考

idba發表於2008-05-06
Buffer Gets    Executions  Gets per Exec  %Total Time (s)  Time (s) Hash Value
------------- ------------ -------------- ------ -------- --------- ----------
116,608,373      164,083          710.7   40.6  7027.07  11922.30 3701069644
Module: java@test.cm2 (TNS V1-V3)
           select count(*)           from test
   where  username = :1    --這是一個高勢列,
   and    ends>sysdate
   and approve_status in (0,1,-9)
   and id <> :2            --這是主鍵
   and promoted_status = 1

如果大家見到這樣的SQL語句會怎麼樣優化?通常的做法,是在當前索引中冗餘id欄位,以避免回表。但這樣要去調整這張大表的索引.

在看到上面的SQL後,詢問開發能否明確的知道id=:2並且滿足其它條件的這樣的記錄是否一定存在。開發經過查證後,最後的答覆是無法肯定.既然在應用層無法確定,那也要想個辦法來解決大量回表的問題。在經過仔細觀察後,我將上面這條SQL語句轉換成下面兩條SQL以及最後一步應用邏輯來實現:

第一條SQL:

Select/*+ index(a, PK_test_ID) */ count(*)   from test a
   where id=:1 and  ends>sysdate and approve_status in (0,1,-9)  and promoted_status = 1 and username=:2

第二條SQL:

select count(*)    from test
   where  username = :1 and     ends>sysdate and approve_status in (0,1,-9) and     and promoted_status = 1

第三步,將兩個結果相減即可實現業務

我們在做SQL優化時,如何把一條SQL根據需要等價轉化成多條,需要考慮當前的應用邏輯,以及當前資料庫中索引的情況,優化便會事半功倍。如何跳出ORACLE去思考問題,希望這個優化案例能對大家有所啟示。

<!--

--EOF--

作者:丹臣 | 【轉載時請務必以超連結形式標明文章原始出處和作者資訊及本宣告】
地址:http://rdc.taobao.com/blog/dba/html/140_sql_performance_tuning_dc.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1384/viewspace-261575/,如需轉載,請註明出處,否則將追究法律責任。

相關文章