2016-03-03 136 views
0

在沒有收集表統計信息(使用dbms_stat.gather_table_stat)和收集表統計信息並運行執行計劃的情況下運行執行計劃是否會執行計劃中的任何更改。是否有人請解釋收集表統計信息以及如何執行計劃依賴於收集統計信息。GATHER_TABLE_STATS和oracle中的執行計劃

+2

我投票關閉這一問題作爲題外話,因爲它不是編程並可能更適合http://dba.stackexchange.com/ – DaImTo

+0

[Oracle如何使用統計數據]的可能重複(http://stackoverflow.com/questions/1832822/how-oracle-uses-statistics-data ) –

回答

0

執行計劃基於統計。如果你知道它並且下面的示例對你沒有用,請說出來,我將刪除這篇文章。謝謝。 作爲例子,我創建了兩個表:

create table ag_test1 (id1 number, val varchar2(50)); 
alter table ag_test1 add constraint pk_ag_test1 primary key (id1); 
create table ag_test2 (id2 number, val varchar2(50)); 
alter table ag_test2 add constraint pk_ag_test2 primary key (id2); 

再之後,我收集統計該表:

begin 
    dbms_stats.gather_table_stats(ownname => user,tabname => 'AG_TEST1', cascade =>true); 
    dbms_stats.gather_table_stats(ownname => user,tabname => 'AG_TEST2', cascade =>true); 
end; 

並運行查詢:

select /* test_query_1 */ 
     t1.val as tbl1, t2.val as tbl2 
from ag_test1 t1 
join ag_test2 t2 on (t1.id1 = t2.id2); 

外觀上執行計劃(你還記得表包含0行):

-------------------------------------------------------------------------------------------- 
| Id | Operation     | Name  | Rows | Bytes | Cost (%CPU)| Time  | 
-------------------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT    |    |  |  |  2 (100)|   | 
| 1 | NESTED LOOPS    |    |  1 | 80 |  2 (0)| 00:00:01 | 
| 2 | NESTED LOOPS    |    |  1 | 80 |  2 (0)| 00:00:01 | 
| 3 | TABLE ACCESS FULL   | AG_TEST1 |  1 | 40 |  2 (0)| 00:00:01 | 
|* 4 | INDEX UNIQUE SCAN   | PK_AG_TEST2 |  1 |  |  0 (0)|   | 
| 5 | TABLE ACCESS BY INDEX ROWID| AG_TEST2 |  1 | 40 |  0 (0)|   | 
-------------------------------------------------------------------------------------------- 

讓我們填寫此表(1M行到每個表):再次

insert all 
when 1=1 then 
    into ag_test1 (id1, val) 
    values (lvl, val1) 
when 1=1 then 
    into ag_test2 (id2, val) 
    values (lvl, val2) 
select level as lvl, 'TBL1_VAL_'||level as val1, 'TBL2_VAL_'||level as val2 
from dual 
connect by level <=1000000; 
commit; 

運行查詢,並期待:

-------------------------------------------------------------------------------------------- 
| Id | Operation     | Name  | Rows | Bytes | Cost (%CPU)| Time  | 
-------------------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT    |    |  |  |  2 (100)|   | 
| 1 | NESTED LOOPS    |    |  1 | 80 |  2 (0)| 00:00:01 | 
| 2 | NESTED LOOPS    |    |  1 | 80 |  2 (0)| 00:00:01 | 
| 3 | TABLE ACCESS FULL   | AG_TEST1 |  1 | 40 |  2 (0)| 00:00:01 | 
|* 4 | INDEX UNIQUE SCAN   | PK_AG_TEST2 |  1 |  |  0 (0)|   | 
| 5 | TABLE ACCESS BY INDEX ROWID| AG_TEST2 |  1 | 40 |  0 (0)|   | 
-------------------------------------------------------------------------------------------- 

什麼都沒有改變。 1M行的執行計劃等於0行。因爲Oracle使用軟解析(查找並使用以前的計劃)。讓我們收集統計與no_invalidate條款(no_invalidate =>假):

begin 
    dbms_stats.gather_table_stats(ownname => user,tabname => 'AG_TEST1', cascade =>true, no_invalidate => false); 
    dbms_stats.gather_table_stats(ownname => user,tabname => 'AG_TEST2', cascade =>true, no_invalidate => false); 
end; 

並期待在執行計劃:

--------------------------------------------------------------------------------------- 
| Id | Operation   | Name  | Rows | Bytes |TempSpc| Cost (%CPU)| Time  | 
--------------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |   |  |  |  | 5120 (100)|   | 
|* 1 | HASH JOIN   |   | 1000K| 40M| 31M| 5120 (1)| 00:00:01 | 
| 2 | TABLE ACCESS FULL| AG_TEST1 | 1000K| 20M|  | 995 (1)| 00:00:01 | 
| 3 | TABLE ACCESS FULL| AG_TEST2 | 1000K| 20M|  | 995 (1)| 00:00:01 | 
---------------------------------------------------------------------------------------