Oracle直方圖詳解(ZT)
下面透過一個具體的例子解釋柱狀圖的使用。
SQL>
create table tab (a number, b number);
Table created.
SQL>
begin
for i in 1..10000 loop
insert into tab values (i,
i);
end loop;
commit;
end;
/
PL/SQL
procedure successfully completed.
SQL> update tab set b=5 where b
between 6 and 9995;
9990 rows updated.
SQL>
commit;
Commit
complete.
這樣在tab表中,b列有10個不同的值,其中等於的值有9991個。在建立索引之前,無論是查詢b=3或者是b=5,都只能是走全表掃描(FULL
TABLE SCAN),因為沒有別的可以使用的訪問路徑。
下面我們在b列上建立一個索引。
SQL> create index
ix_tab_b on tab(b);
Index created.
SQL> select index_name,
table_name, column_name, column_position, column_length
from
user_ind_columns
where
table_name='TAB';
INDEX_NAME
TABLE_NAME COLUMN_NAME COLUMN_POSITION
COLUMN_LENGTH
------------------------------ ------------------------------
-------------------- ---------------
-------------
IX_TAB_B TAB
B 1
22
現在我們分別來看看下面的查詢。
SQL> select * from tab where b=3;
1
rows selected.
Execution
Plan
----------------------------------------------------------
Plan hash
value: 439197569
------------------------------------------------
| Id
| Operation | Name
|
------------------------------------------------
| 0 | SELECT
STATEMENT | |
| 1 | TABLE ACCESS BY INDEX ROWID|
TAB |
|* 2 | INDEX RANGE SCAN | IX_TAB_B
|
------------------------------------------------
Statistics
----------------------------------------------------------
178 recursive calls
0 db block gets
30 consistent
gets
5 physical reads
116 redo size
462 bytes
sent via SQL*Net to client
385 bytes received via SQL*Net from
client
2 SQL*Net roundtrips to/from client
5 sorts
(memory)
0 sorts (disk)
1 rows
processed
SQL> select * from tab where b=5;
9991 rows
selected.
Execution
Plan
----------------------------------------------------------
Plan hash
value: 439197569
------------------------------------------------
| Id
| Operation | Name
|
------------------------------------------------
| 0 | SELECT
STATEMENT | |
| 1 | TABLE ACCESS BY INDEX ROWID|
TAB |
|* 2 | INDEX RANGE SCAN | IX_TAB_B
|
------------------------------------------------
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
1370 consistent
gets
16 physical reads
0 redo size
206729 bytes
sent via SQL*Net to client
7711 bytes received via SQL*Net from
client
668 SQL*Net roundtrips to/from client
0 sorts
(memory)
0 sorts (disk)
9991 rows
processed
可以看出這裡走的都是基於RBO的INDEX RANGE
SCAN。
接下來,我們使用計算統計對錶進行分析。
SQL> analyze table tab compute
statistics;
Table analyzed.
SQL> select num_rows, blocks,
empty_blocks, avg_space, chain_cnt, avg_row_len
2 from dba_tables
3 where
table_name = 'TAB';
NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE CHAIN_CNT
AVG_ROW_LEN
---------- ---------- ------------ ---------- ----------
-----------
10000 20 4 2080 0
10
SQL> select num_distinct, low_value, high_value, density,
num_buckets, last_analyzed, sample_size
from dba_tab_columns
where table_name = 'TAB';
NUM_DISTINCT LOW_VALUE
HIGH_VALUE DENSITY NUM_BUCKETS LAST_ANAL
SAMPLE_SIZE
------------ -------------------- -------------------- ----------
----------- --------- -----------
10000 C102
C302 .0001 1 21-DEC-08 10000
10 C102 C302 .1 1
21-DEC-08 10000
SQL> select table_name, column_name,
endpoint_number, endpoint_value
from dba_tab_histograms
where
table_name = 'TAB';
TABLE_NAME COLUMN_NAME
ENDPOINT_NUMBER ENDPOINT_VALUE
------------------------------
-------------------- ---------------
--------------
TAB
A 0
1
TAB A
1 10000
TAB
B 0
1
TAB B
1 10000
再來執行上面的兩個查詢,觀察其執行計劃,發現兩個查詢仍然走的都是INDEX RANGE
SCAN,只不過這時的執行計劃是基於CBO的。
現在我們建立tab表b列的柱狀圖統計資訊,使得最佳化器能夠知道該列每個值的具體分佈情況。
SQL>
analyze table tab compute statistics for columns b size 10;
Table
analyzed.
SQL> select table_name, column_name, endpoint_number,
endpoint_value
from dba_histograms
where table_name =
'TAB';
TABLE_NAME COLUMN_NAME
ENDPOINT_NUMBER ENDPOINT_VALUE
------------------------------
-------------------- ---------------
--------------
TAB
B 1
1
TAB B
2 2
TAB
B 3
3
TAB B
4 4
TAB
B 9995
5
TAB B
9996 9996
TAB
B 9997
9997
TAB B
9998 9998
TAB
B 9999
9999
TAB B
10000
10000
直方圖中的ENDPOINT_VALUE表示列值,ENDPOINT_NUMBER表示累積的行數。比如ENDPOINT_VALUE=2,ENDPOINT_NUMBER=2,因為ENDPOINT_NUMBER是個累積值,實際上2的ENDPOINT_NUMBER應該是2減去上一個值的ENDPOINT_NUMBER,也即是2-1=1。同理,5的ENDPOINT_NUMBER=9995-4=9991。
SQL>
select * from tab where b=3;
1 rows selected.
Execution
Plan
----------------------------------------------------------
Plan hash
value:
439197569
----------------------------------------------------------------------------------------
|
Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
Time
|
----------------------------------------------------------------------------------------
|
0 | SELECT STATEMENT | | 1 | 6 | 2 (0)|
00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TAB | 1 | 6
| 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IX_TAB_B |
1 | | 1 (0)| 00:00:01
|
----------------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
178 recursive calls
0 db block gets
28 consistent
gets
0 physical reads
0 redo size
462 bytes
sent via SQL*Net to client
385 bytes received via SQL*Net from
client
2 SQL*Net roundtrips to/from client
5 sorts
(memory)
0 sorts (disk)
1 rows
processed
SQL> select * from tab where b=5;
9991 rows
selected.
Execution
Plan
----------------------------------------------------------
Plan hash
value:
1995730731
--------------------------------------------------------------------------
|
Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
|
--------------------------------------------------------------------------
|
0 | SELECT STATEMENT | | 9991 | 59946 | 6 (0)| 00:00:01 |
|* 1 |
TABLE ACCESS FULL| TAB | 9991 | 59946 | 6 (0)| 00:00:01
|
--------------------------------------------------------------------------
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
689 consistent
gets
0 physical reads
0 redo size
174757 bytes
sent via SQL*Net to client
7711 bytes received via SQL*Net from
client
668 SQL*Net roundtrips to/from client
0 sorts
(memory)
0 sorts (disk)
9991 rows
processed
這時可以看出,不同值的分佈導致了Oracle最佳化器選擇了不同執行計劃。對於b=5的查詢來說,全表掃描的一致性讀比之前的索引範圍掃描要降低很多。可以看出此時的全表掃描比之索引範圍掃描更加的合理,最佳化器正是根據直方圖的統計資訊做出的正確的判斷。
上述的例子描述了一種理想的狀況,因為我們為每一個不同的值建立了bucket。在實際的生產系統中,一張表可能包含很多的唯一值,我們不可能為每一個唯一值建立bucket,這樣開銷將是巨大的。
下面的例子描述了唯一值大於buckets的情況。
SQL>
analyze table tab compute statistics for columns b size 8;
Table
analyzed.
SQL> select table_name, column_name, endpoint_number,
endpoint_value
from dba_histograms
where table_name =
'TAB';
TABLE_NAME COLUMN_NAME
ENDPOINT_NUMBER ENDPOINT_VALUE
------------------------------
-------------------- ---------------
--------------
TAB
B 0
1
TAB B
7 5
TAB
B 8
10000
ENDPOINT_NUMBER是實際的bucket編號,ENDPOINT_VALUE是根據列值決定的該bucket的endpoint值。上面的輸出中,bucket
0存放著b列的低值,為了節省空間沒有顯示出1-6號的bucket。但是我們能夠理解,bucket[1-7]裡存放著的endpoint=5,而bucket8裡存放endpoint=10000。因此,實際上bucket0裡包含了1-5之間的所有值,而bucket8裡包含了5-10000之間的所有值,在本例中也就是9996-10000這5個數值。
綜上所述,假如資料是均衡的,沒有必要使用直方圖。如果使用唯一值數量來建立直方圖,Oracle為每個值建立一個bucket;但是假如實際的生產系統中,不能夠為每一個唯一值分配一個bucket時,Oracle採用合適的演算法儘可能將值平均分佈到每個bucket中,剩餘的值放入到最後的bucket。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/271283/viewspace-1022680/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle直方圖詳解Oracle直方圖
- (轉)Oracle直方圖詳解Oracle直方圖
- Oracle直方圖 (柱狀圖 histograms) 詳解Oracle直方圖Histogram
- [zt] Histograms - 直方圖Histogram直方圖
- oracle 直方圖Oracle直方圖
- oracle直方圖使用Oracle直方圖
- Oracle直方圖解析Oracle直方圖圖解
- oracle直方圖筆記-轉Oracle直方圖筆記
- 直方圖直方圖
- oracle直方圖histogram小記(一)Oracle直方圖Histogram
- 轉貼oracle直方圖histogram(二)Oracle直方圖Histogram
- 【效能優化】Oracle直方圖解析優化Oracle直方圖圖解
- oracle統計資訊和直方圖Oracle直方圖
- 收集直方圖及檢視直方圖資訊直方圖
- oracle統計資訊--直方圖的收集:Oracle直方圖
- 直方圖(histograms)直方圖Histogram
- 7.3 直方圖直方圖
- 柱狀圖、直方圖、散點圖、餅圖講解直方圖
- Oracle直方圖統計資訊的應用Oracle直方圖
- Oracle直方圖 32位元組限制Oracle直方圖
- 直方圖均衡化直方圖
- 04:垂直直方圖直方圖
- 直方圖學習直方圖
- dba_histograms等高直方圖和等頻直方圖的理解Histogram直方圖
- ORACLE的直方圖的一些試驗Oracle直方圖
- [轉] oracle統計資訊(statistics)和直方圖(histogram)Oracle直方圖Histogram
- [20170615]直方圖-高度直方圖(11g).txt直方圖
- Oracle中的Hash Join詳解 ztOracle
- 直方圖中最大矩形直方圖
- 【效能優化】直方圖優化直方圖
- 【opencv學習筆記】027之直方圖反向投影 - calcBackProject函式詳解OpenCV筆記直方圖Project函式
- 【數字影像處理】直方圖均衡化詳解及程式設計實現直方圖程式設計
- [Python影象處理] 十一.灰度直方圖概念及OpenCV繪製直方圖Python直方圖OpenCV
- OpenCV計算機視覺學習(9)——影像直方圖 & 直方圖均衡化OpenCV計算機視覺直方圖
- halcon-直方圖均衡直方圖
- python如何畫直方圖Python直方圖
- elasticsearch 之 histogram 直方圖聚合ElasticsearchHistogram直方圖
- 使用直方圖注意事項直方圖