在收集統計資訊時指定method_opt=>.. size auto 時,有可能不收集直方圖

hurp_oracle發表於2014-05-31
DBMS_STATS With METHOD_OPT =>'..SIZE auto' May Not Collect Histograms (文件 ID 557594.1)


在收集統計資訊時指定method_opt=>.. size auto 時,有可能不收集直方圖。


APPLIES TO:


Oracle Server - Enterprise Edition - Version 10.2.0.1 and later
Information in this document applies to any platform.




SYMPTOMS


After stats are first gathered using DBMS_STATS with  METHOD_OPT =>'FOR all COLUMNS SIZE auto', query runs poorly.


Histograms are not collected properly on the columns.  After re-gathering the stats with the same procedure, the query runs fine.


症狀:
第一次用size auto收集統計資訊,查詢緩慢
原因直方圖沒有被收集,用同樣的過程重新收集後,查詢速度變快


CAUSE


When 'SIZE AUTO' is specified, histograms are considered by information of col_usage$. If a column (mycol in this case) has its column statistics and it is used in predicates of SQL statements, then col_usage$ is updated to show that the column has been used as predicates. When DBMS_STATS.GATHER_TABLE_STATS is executed with 'SIZE AUTO' specified, it checks col_usage$ to see whether the column has been used as predicates or not . If it has, histogram is considered for that column.  


size auto收集直方圖的條件:
1.列的資料傾斜。
2.列在查詢語句中做謂語


測試:


SQL> create table hurp (mycol number);


Table created.




--插入1000條-1
begin 
for i in 1 .. 100000 loop 
insert into hurp values (-1);
commit;
end loop;


for i in 1 .. 1000 loop
insert into hurp values (0);
commit;
end loop;


for i in 1 .. 100 loop
insert into hurp values(7);
commit;
end loop;
end;
/


PL/SQL procedure successfully completed.


---建立索引對列mycol
SQL> create index indx_hurp on hurp(mycol);


Index created.


--對列索引列收集統計資訊
begin 
dbms_stats.gather_table_stats(ownname =>'SYS',
tabname =>'HURP',
method_opt =>'for all indexed columns size auto',
cascade =>TRUE);
end;
/


select lpad(owner,5) owner,
       lpad(table_name,5)table_name,
       column_name,
       endpoint_value,
       endpoint_number 
  from dba_histograms 
 where owner='SYS' 
   and table_name='HURP';
   
OWNER      LPAD(TABLE COLUMN_NAME                    ENDPOINT_VALUE ENDPOINT_NUMBER
---------- ---------- ------------------------------ -------------- ---------------
  SYS       HURP      MYCOL                                      -1               0
  SYS       HURP      MYCOL                                       7               1
  
-- Update col_usage$ 
SQL> select count(*) from hurp where mycol = 1; 


  COUNT(*)
----------
         0


---重新收集統計資訊
SQL> begin 
  2  dbms_stats.gather_table_stats(ownname =>'SYS',
  3  tabname =>'HURP',
  4  method_opt =>'for all indexed columns size auto',
  5  cascade =>TRUE);
  6  end;
  7  /


PL/SQL procedure successfully completed.


---檢視發現已經有了直方圖
SQL> select lpad(owner,5) owner,
  2         lpad(table_name,5)table_name,
  3         column_name,
  4         endpoint_value,
  5         endpoint_number 
  6    from dba_histograms 
  7   where owner='SYS' 
  8     and table_name='HURP';


OWNER      TABLE_NAME COLUMN_NAME                    ENDPOINT_VALUE ENDPOINT_NUMBER
---------- ---------- ------------------------------ -------------- ---------------
  SYS       HURP      MYCOL                                      -1            5419
  SYS       HURP      MYCOL                                       0            5472
  SYS       HURP      MYCOL                                       7            5480
  
select count(*)from hurp where mycol=-1;  












-----測試資料不傾斜
drop table hurp purge;
create table hurp(mycol number);


begin 
for i in 1 .. 10000 loop
insert into hurp values(-1);
commit;
end loop;


for i in 1 .. 10000 loop 
insert into hurp values(0);
commit;
end loop;


for i in 1 .. 10000 loop
insert into hurp values(7);
commit;
end loop;
end;
/


create index indx_hurp on hurp(mycol);






select count(*) from hurp where mycol=1;


exec dbms_stats.flush_database_monitoring_info;


begin
dbms_stats.gather_table_stats(ownname=>'SYS',
tabname=>'HURP',
method_opt=>'for all indexed columns size auto',
cascade=>true);
end;
/


select lpad(owner,5) owner,lpad(table_name,5) table_name,column_name,endpoint_value,endpoint_number from dba_histograms where owner='SYS' and table_name='HURP';


  
  


begin 
dbms_stats.gather_table_stats(ownname =>'SYS',
tabname =>'TEST',
method_opt =>'for all columns size auto',
cascade =>TRUE);
end;
/




select lpad(owner,5) owner,lpad(table_name,5) table_name,column_name,endpoint_value,endpoint_number from dba_histograms where owner='SYS' and table_name='TEST';


SELECT OWNER,TABLE_NAME,BU


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

相關文章