保障執行計劃正確

現在項目中經常 出現有的時候 SQL跑的很快,  有時候確像 蝸牛。。

我當時覺得奇怪, 爲啥 哥優化好了一個SQL, 怎麼 又慢的??  於是哥開始反思,      這個哥的第一反應是  統計信息導致的問題。  統計信息 把rows 算的錯誤的太離譜了。

導致本來走hash 的走了  NL。


於是哥找出SQl, 看了下執行計劃, 果然

/*
1 Plan hash value: 2350308821

3 -----------------------------------------------------------------------------------------------------
4 | Id  | Operation                     | Name                | Rows  | Bytes | Cost (%CPU)| Time     |
5 -----------------------------------------------------------------------------------------------------
6 |   0 | SELECT STATEMENT              |                     |     1 |   105 |     7   (0)| 00:00:01 |
7 |   1 |  SORT AGGREGATE               |                     |     1 |   105 |            |          |
8 |   2 |   NESTED LOOPS OUTER          |                     |     1 |   105 |     7   (0)| 00:00:01 |
9 |   3 |    NESTED LOOPS               |                     |     1 |    84 |     4   (0)| 00:00:01 |
10  |   4 |     NESTED LOOPS OUTER        |                     |     1 |    77 |     3   (0)| 00:00:01 |
11  |   5 |      TABLE ACCESS FULL        | T_PUB_BILL_ACTION_3 |     1 |    67 |     2   (0)| 00:00:01 |
12  |*  6 |      INDEX RANGE SCAN         | DIM_TASK_SPEC_IDX   |     1 |    10 |     1   (0)| 00:00:01 |
13  |*  7 |     INDEX RANGE SCAN          | IDX_OPENBILL_3      |     1 |     7 |     1   (0)| 00:00:01 |
14  |*  8 |    TABLE ACCESS BY INDEX ROWID| DIM_STAFF           |     1 |    21 |     3   (0)| 00:00:01 |
15  |*  9 |     INDEX RANGE SCAN          | IDX_DIM_STAFF       |     2 |       |     1   (0)| 00:00:01 |
16  ----------------------------------------------------------------------------------------------------- 

一看 果然錯誤的太離譜了,  CBO 算成1了,   這裏哥 想到了, 用hint 固定執行計劃, 發現這個固然可以, 但是 哥想到爲啥  算成1了。  

哥看了一下 統計信息 收集的時間, 一看發現 好像是在 9點17分鐘的樣子收集的,    哥明白了。

這個正是由於truncate  table 導致的, 哥查了V$SQL , 發現這樣搞的還蠻頻繁的,   truncate 之後, 正好 oracle 來收集統計信息了, 於是哥又收集了一下統計信息 

於是哥 看了一下執行計劃, 果然變了 , 變成hash 了。 


/*
1 Plan hash value: 1978552090

3 ------------------------------------------------------------------------------------------------------
4 | Id  | Operation              | Name                | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
5 ------------------------------------------------------------------------------------------------------
6 |   0 | SELECT STATEMENT       |                     |  1047K|   163M|       | 24493   (1)| 00:04:54 |
7 |*  1 |  HASH JOIN RIGHT OUTER |                     |  1047K|   163M|       | 24493   (1)| 00:04:54 |
8 |*  2 |   TABLE ACCESS FULL    | DIM_TASK_SPEC       |    51 |  1479 |       |     3   (0)| 00:00:01 |
9 |*  3 |   HASH JOIN RIGHT OUTER|                     |  1047K|   134M|  4544K| 24483   (1)| 00:04:54 |
10  |*  4 |    TABLE ACCESS FULL   | DIM_STAFF           | 81538 |  3583K|       |   231   (1)| 00:00:03 |
11  |*  5 |    HASH JOIN           |                     |  1047K|    89M|  4504K| 18966   (1)| 00:03:48 |
12  |   6 |     TABLE ACCESS FULL  | T_OPEN_BILLINFO_3   |   100K|  3323K|       |  4625   (1)| 00:00:56 |
13  |   7 |     TABLE ACCESS FULL  | T_PUB_BILL_ACTION_3 |  1047K|    55M|       | 10741   (1)| 00:02:09 |
14  ------------------------------------------------------------------------------------------------------
15  
16  Predicate Information (identified by operation id):
17  ---------------------------------------------------
18  
19     1 - access("D"."TASK_SPEC_ID"(+)="A"."ACTION_TYPE")
20     2 - filter("D"."SYS_ID"(+)=4)
21     3 - access("C"."ORG_ID"(+)="A"."OPERATOR_GROUP" AND "C"."STAFF_ID"(+)="A"."OPERATOR")
22     4 - filter("C"."SYS_ID"(+)=4)
23     5 - access("A"."BILL_ID"="B"."BILL_ID")*/   

這個由於經常要 truncate 。 於是 哥需要 固定執行計劃, 用hint 固定也可以,  但開發人員好像不太會搞 hint,  那哥只好第二招,讓

開發人員方便開發,  固定統計信息。

於是哥,   DBMS_STATS.lock_table_stats ,    那就以下腳本



 DBMS_STATS.GATHER_TABLE_STATS(OWNNAME => 'JS_ZWXN', TABNAME  => 'T_PUB_BILL_ACTION_3', ESTIMATE_PERCENT => 100, METHOD_OPT => 'for all columns size repeat', DEGREE => 8,  GRANULARITY => 'ALL',CASCADE => TRUE);

    DBMS_STATS.lock_table_stats(OWNNAME => 'JS_ZWXN', TABNAME  => 'T_PUB_BILL_ACTION_3');


 對了優化前後  效率提高 20多倍吧,      如果兩個表在數據量 最多時候算,  能提升100多倍。


 所以 優化來說, 肯定保證 統計信息 正確, 起碼不能錯誤的太離譜了。 









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