Oracle直方圖統計資訊的應用
Oracle直方圖統計資訊說明了表中資料的分佈情況,用於在表中資料分佈十分不均衡的情況下,指導CBO最佳化器選擇最優的執行計劃。以下例子說明了這一應用。
建立表
create table scott.t(id number);
建立索引
create index scott.idx_t_id on scott.t(id) compute statistics parallel;
插入資料
begin
for i in 1 .. 29990 loop
insert into scott.t values (1);
end loop;
commit;
end;
/
begin
for i in 29991 .. 30000 loop
insert into scott.t values (mod(i, 7));
end loop;
commit;
end;
/
檢視資料分佈
select id,
count(*) cardinality,
sum(count(*)) over(order by id range unbounded preceding) sum_cardinality
from scott.t
group by id;
ID CARDINALITY SUM_CARDINALITY
---------- ----------- ---------------
0 1 1
1 29991 29992
2 1 29993
3 2 29995
4 2 29997
5 2 29999
6 1 30000
可以看到表中資料的分佈嚴重不均衡,ID為0、2和6的記錄各只有1條,而ID為1的記錄有29991條,ID為3、4、5的記錄也各只有1條。
在這種情況下執行查詢,看執行計劃,可以看到,由於謂詞ID=1選擇性差,導致採用全表掃描
set autot trace exp
select * from scott.t where id=1;
執行計劃
----------------------------------------------------------
Plan hash value: 1601196873
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 29991 | 89973 | 15 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T | 29991 | 89973 | 15 (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("ID"=1)
下面查詢唯一性高的條件,由於謂詞ID=0選擇性好,因此採用了索引掃描
select * from scott.t where id=0;
執行計劃
----------------------------------------------------------
Plan hash value: 371777749
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 3 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IDX_T_ID | 1 | 3 | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("ID"=0)
建立與distinct_keys=7相等數量的寬度均衡的直方圖
begin
dbms_stats.gather_table_stats(ownname => 'SCOTT',
tabname => 'T',
estimate_percent => 100,
method_opt => 'FOR COLUMNS SIZE 7 ID',
degree => 4,
cascade => true);
end;
/
查詢直方圖buckets資料分佈資訊
col owner for a10
col table_name for a20
col column_name for a20
col endpoint_number for a20
col endpoint_value for a20
select h.owner,
h.table_name,
h.column_name,
to_char(h.endpoint_number) endpoint_number,
to_char(h.endpoint_value) endpoint_value
from dba_histograms h
where h.owner = 'SCOTT'
and h.table_name = 'T';
OWNER TABLE_NAME COLUMN_NAME ENDPOINT_NUMBER ENDPOINT_VALUE
---------- -------------------- -------------------- -------------------- --------------------
SCOTT T ID 1 0
SCOTT T ID 29992 1
SCOTT T ID 29993 2
SCOTT T ID 29995 3
SCOTT T ID 29997 4
SCOTT T ID 29999 5
SCOTT T ID 30000 6
在直方圖統計資訊的基礎上如果不使用繫結變數,查詢選擇性低的謂詞也是不會走索引的
select * from scott.t where id=1;
執行計劃
----------------------------------------------------------
Plan hash value: 1601196873
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 29991 | 89973 | 15 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T | 29991 | 89973 | 15 (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("ID"=1)
但如果使用繫結變數,效果就不一樣了
var i number
exec :i:=1;
select * from scott.t where id=:i;
執行計劃
----------------------------------------------------------
Plan hash value: 371777749
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4286 | 12858 | 9 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IDX_T_ID | 4286 | 12858 | 9 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("ID"=TO_NUMBER(:I))
以上測試說明,在表中資料分佈不均衡的情況下執行選擇性低的查詢,如果有完整準確的直方圖統計資訊,並且採用繫結變數,CBO會選擇索引掃描。如果沒有直方圖資訊,CBO將不走索引而選擇全表掃描。此處使用直方圖統計資訊使得查詢效能得到了較大提升。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28974745/viewspace-2146890/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle統計資訊--直方圖的收集:Oracle直方圖
- oracle統計資訊和直方圖Oracle直方圖
- Oracle的自動統計資訊不收集直方圖的資訊Oracle直方圖
- [轉] oracle統計資訊(statistics)和直方圖(histogram)Oracle直方圖Histogram
- 關於列的直方圖統計資訊直方圖
- 收集資料庫統計資訊需要收集直方圖資訊.資料庫直方圖
- 收集直方圖及檢視直方圖資訊直方圖
- oracle 直方圖Oracle直方圖
- oracle直方圖使用Oracle直方圖
- Oracle直方圖解析Oracle直方圖圖解
- Oracle資料遷移後由列的直方圖統計資訊引起的執行計劃異常Oracle直方圖
- Oracle直方圖詳解Oracle直方圖
- Oracle多列統計資訊與直方圖對有關聯多列查詢影響Oracle直方圖
- OpenCV成長之路(5):影象直方圖的應用OpenCV直方圖
- oracle直方圖筆記-轉Oracle直方圖筆記
- (轉)Oracle直方圖詳解Oracle直方圖
- Oracle直方圖詳解(ZT)Oracle直方圖
- 微課sql最佳化(7)、統計資訊收集(5)-關於直方圖SQL直方圖
- 直方圖直方圖
- oracle直方圖histogram小記(一)Oracle直方圖Histogram
- 轉貼oracle直方圖histogram(二)Oracle直方圖Histogram
- 【效能優化】Oracle直方圖解析優化Oracle直方圖圖解
- Oracle直方圖 (柱狀圖 histograms) 詳解Oracle直方圖Histogram
- ORACLE的直方圖的一些試驗Oracle直方圖
- 等頻直方圖,計算COST直方圖
- OpenCV計算機視覺學習(9)——影像直方圖 & 直方圖均衡化OpenCV計算機視覺直方圖
- dba_histograms等高直方圖和等頻直方圖的理解Histogram直方圖
- 直方圖(histograms)直方圖Histogram
- 7.3 直方圖直方圖
- 11G,可以只刪除直方圖資訊直方圖
- Javafx-【直方圖】文字頻次統計工具 中文/英文單詞統計Java直方圖
- Oracle直方圖 32位元組限制Oracle直方圖
- 優化由直方圖資訊導致的sql效能問題優化直方圖SQL
- 在收集統計資訊時指定method_opt=>.. size auto 時,有可能不收集直方圖直方圖
- 直方圖均衡化直方圖
- 04:垂直直方圖直方圖
- 直方圖學習直方圖
- [zt] Histograms - 直方圖Histogram直方圖