1. 程式人生 > >理解執行計劃中的一些sort操作

理解執行計劃中的一些sort操作

理解sort操作,其實很簡單,核心的就是sort,後面括弧裡面說明的是排序的目的是什麼?版本:9.2.0.8
當需要排序操作時,通常會有一系列sort的操作,下面是一些cbo執行sort的操作:
Sort unique(sort的目的是取出所有的唯一值)
Sort aggregate(sort的目的是為了聚合)//聚合函式如count()、sum()等就是聚合操作
Sort group by(sort的目的是為了分組)
Sort join(sort的目的是為了merge)
Sort order by(sort的目的是為了有序輸出)

分別來看這些操作的產生和執行情況:
Sort unique
Sort unique在distinct操作或者某個下一步需要unique值的操作:
SQL> select distinct a.state from t_policy_state a;

36 rows selected.


Execution Plan
----------------------------------------------------------
  0     SELECT STATEMENT ptimizer=CHOOSE (Cost=18 Card=36 Bytes=828
         )

  1   0  SORT (UNIQUE)(Cost=18 Card=36 Bytes=828)
  2   1    TABLE ACCESS (FULL) OF 'T_POLICY_STATE' (Cost=2 Card=36
         Bytes=828)
另外在某些in子查詢中也有可能產生。

Sort group by
Sort group by用來在計算不同分組的排序時使用
SQL> select a.state,sum(a.p_state_id) from t_policy_state a group by a.state;

36 rows selected.


Execution Plan
----------------------------------------------------------
  0     SELECT STATEMENT ptimizer=CHOOSE (Cost=18 Card=36 Bytes=936
         )

  1   0  SORT (GROUP BY)(Cost=18 Card=36 Bytes=936)
  2   1    TABLE ACCESS (FULL) OF 'T_POLICY_STATE' (Cost=2 Card=36
         Bytes=936)

Sort aggregate
這個操作並沒有實際的進行sort,只是在計算所有行的總計時使用
SQL> select sum(a.p_state_id) from t_policy_state a ;


Execution Plan
----------------------------------------------------------
  0     SELECT STATEMENT ptimizer=CHOOSE (Cost=1 Card=1 Bytes=4)
  1   0  SORT (AGGREGATE)
  2   1    INDEX (FULL SCAN) OF 'PK_T_POLICY_STATE' (UNIQUE) (Cost=
         1 Card=36 Bytes=144)

Sort join
通常在sort merge join中出現,如果用來join的行集需要對join key排序的話使用
SQL> select /*+ use_merge(a,b) */
2  a.organ_id
3   from t_company_organ a, t_company b
4  where a.organ_id = b.parent_id;

no rows selected



Execution Plan
----------------------------------------------------------
  0     SELECT STATEMENT ptimizer=CHOOSE (Cost=19 Card=1 Bytes=16)
  1   0  MERGE JOIN(Cost=19 Card=1 Bytes=16)
  2   1    INDEX (FULL SCAN) OF 'PK_T_COMPANY_ORGAN' (UNIQUE) (Cost
         =1 Card=250 Bytes=1500)

  3   1    SORT (JOIN)(Cost=18 Card=1 Bytes=10)
  4   3      TABLE ACCESS (FULL) OF 'T_COMPANY' (Cost=2 Card=1 Byte
         s=10)

Sort order by
當使用了order by,並且沒有在order by的列上有適合的索引,則會使用這個操作:
SQL> select a.organ_id
2   from t_company_organ a, t_company b
3  where a.organ_id = b.parent_id
4  order by a.organ_id;

no rows selected


Execution Plan
----------------------------------------------------------
  0     SELECT STATEMENT ptimizer=CHOOSE (Cost=19 Card=1 Bytes=16)
  1   0  SORT (ORDER BY)(Cost=19 Card=1 Bytes=16)
  2   1    NESTED LOOPS (Cost=3 Card=1 Bytes=16)
  3   2      TABLE ACCESS (FULL) OF 'T_COMPANY' (Cost=2 Card=1 Byte
         s=10)

  4   2      INDEX (UNIQUE SCAN) OF 'PK_T_COMPANY_ORGAN' (UNIQUE)
如果使用sort merge join,使用a.organ_id上的索引,那麼由於索引已經排序,則不會有sort操作,例如:
SQL> select /*+ use_merge(a,b)*/a.organ_id
2   from t_company_organ a, t_company b
3  where a.organ_id = b.parent_id
4  order by a.organ_id;

no rows selected


Execution Plan
----------------------------------------------------------
  0     SELECT STATEMENT ptimizer=CHOOSE (Cost=19 Card=1 Bytes=16)
  1   0  MERGE JOIN (Cost=19 Card=1 Bytes=16)
  2   1    INDEX (FULL SCAN)OF 'PK_T_COMPANY_ORGAN' (UNIQUE) (Cost
         =1 Card=250 Bytes=1500)

  3   1    SORT (JOIN) (Cost=18 Card=1 Bytes=10)
  4   3      TABLE ACCESS (FULL) OF 'T_COMPANY' (Cost=2 Card=1 Byte
         s=10)

上述這些sql在另外一個版本:10.2.0.4中使用的則是hash unique,hash group by等操作。

註釋:sql語句中的不同詞句對應產生執行計劃裡的不同操作。