PL/SQL DEVELOPER執行計劃的查看

這裏,我學到的一個很重要的東西,就是用PL/SQL DEVELOPER去看一條SELECT語句的執行計劃,執行計劃裏面可以看到這條SELECT語句的開銷、I/O操作開銷等數值,可以很清晰地看到語句各個部分的執行效率。選中這條SELECT語句以後,按F5就可以。

         以下面的SELECT語句爲例子: 

PL/SQL DEVELOPER執行計劃的查看 - 花刺 - 我的點點滴滴

   從三張表中取數據,按我以前的想法,只要WHERE語句那裏有能讓三張表連接起來的條件就可以。所以我只使用了:

 

PL/SQL DEVELOPER執行計劃的查看 - 花刺 - 我的點點滴滴

 按F5後,可以看到這樣做的執行計劃如下:

PL/SQL DEVELOPER執行計劃的查看 - 花刺 - 我的點點滴滴

開銷974,其實並不算高。但是加上測試環境的數據庫連接速度確實很慢,導致了經常會出現數據庫連接超時的提示。

         修改後的SELECT語句如下:

PL/SQL DEVELOPER執行計劃的查看 - 花刺 - 我的點點滴滴

      可以看到,修改只是在WHERE裏面多加了兩個關聯條件。此時再按F5看執行計劃:

 

PL/SQL DEVELOPER執行計劃的查看 - 花刺 - 我的點點滴滴

  這時候COST只剩下95了。實際操作中,確實也明顯感到了操作速度的提升。

         執行計劃的執行順序是,從內層至外層,從上往下。比如上面修改後的實行計劃中,數據庫先對ORDER_HEADER的主鍵做了一個索引範圍檢索,然後再對XXWMS_DLX_SERIAL_NUMBER的非唯一性索引XXWMS_DLX_SERIAL_NUMBER_N4做索引範圍檢索。

         在做修改之前,SERIAL_NUMBER表和XXWMS_DLX_SERIAL_NUMBER表使用了循環嵌套(NESTED LOOPS)的連接方法,得到結果後再與ORDER_HEADER進行哈希連接。由於兩個表的數據量都比較大(SERIAL_NUMBER在測試環境中數據量達到一千四百萬條左右),循環嵌套連接的步驟顯然開銷了很多。

         可以猜想,如果循環嵌套連接中其中一個表的數據量小一點,就可以減少很多開銷。於是,在連接條件中多加一條xx.client_id = oh.client_id。這樣就使用了ORDER_HEADER的主鍵去和XXWMS_DLX_SERIAL_NUMBERN4索引進行連接,得到結果以後再去和SERIAL_NUMBER連接。結果在上圖可以看到,COST只有95,大大加快了執行的效率。

         這個經歷讓我覺得PL/SQL的優化相當神奇,效果是一樣的,但只是加一個條件就可以使得執行效率有如此大的提高。就這個改變,使得彈出來的超時提醒的機率大大降低,對於用戶來說這個改變是很重要的。

 其它查看方法:

    

需要先創建plan_table
create table PLAN_TABLE (
        statement_id         varchar2(30),
        timestamp            date,
        remarks              varchar2(80),
        operation            varchar2(30),
        options               varchar2(255),
        object_node          varchar2(128),
        object_owner         varchar2(30),
        object_name          varchar2(30),
        object_instance numeric,
        object_type     varchar2(30),
        optimizer       varchar2(255),
        search_columns  number,
        id                numeric,
        parent_id        numeric,
        position        numeric,
        cost                numeric,
        cardinality        numeric,
        bytes                numeric,
        other_tag       varchar2(255),
        partition_start varchar2(255),
        partition_stop  varchar2(255),
        partition_id    numeric,
        other                long,
        distribution    varchar2(30),
        cpu_cost        numeric,
        io_cost                numeric,
        temp_space        numeric);

建表的sql在rdbms/admin下有,名字是utlxplan.sql
我用的是9i,其他版本的名字可能不一樣,
然後執行
explain plan for sql語句
然後可以執行這個sql看結果
SELECT LPAD (' ', 2 * LEVEL) ||
       operation ||
       ' ' ||
       options ||
       ' ' ||
       object_name query_plan
  FROM plan_table
CONNECT BY PRIOR id = parent_id
START WITH id = 1
ORDER BY id;


另摘:

執行後下面有一些信息,看cost列,一般越小效率越高,還有看Description列,有沒有table access
 full 這種全表掃描標誌的,一般查詢大表要避免全表掃描。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章