**:
oracle 聚簇因子
oracle中,對於同乙個查詢語句,有時候會很快的完成,有時候卻很慢,但是表結構什麼的完全一致,表中的資料也完全一致,這個具體是什麼原因呢,就要從index中的細節說起了。
在oracle中的乙個特殊的檢視user_indexes中有乙個特殊的列,名字是clustering_factor,這個值的內容就是如果訪問表的整個表資料,會造成多少次資料庫io。
a:如果這個值與塊數接近,則說明表相當有序,得到了很好的組織。在這種情況下,同乙個葉子塊中的索引條目可能指向同乙個資料塊中的行。
b:如果這個值與行數接近,表的次序可能就是非常隨機的。在這種情況下,同乙個葉子塊上的索引條目不太可能指向同乙個資料塊上的行。
可以把聚簇因子看作是通過索引讀取整個表時對錶執行的邏輯i/o次數。也就是說侷促因子指示了表相對於索引本身的有序程度。當oracle對索引結構執行區間掃瞄時,如果它發現索引中的下一行與前一行在同乙個資料塊上,就不會再執行另乙個i/o從緩衝區快取中獲得表塊。它已經有了表塊的乙個控制代碼,只需要直接使用就行了。不過,如果下一行不在同乙個塊上,就會釋放當前的這個塊,而執行另乙個物理i/o在緩衝區快取存放要處理的下乙個塊。
我們在查詢索引狀態的時候,通常會用到user_indexes這張表,這張表中有一列(clustering_factor 聚簇因子),這裡簡單的介紹下聚簇因子的意思,大家知道資料表中的資料都是無序的存在庫中,當我們在對資料進行檢索的時候,查詢起來很是耗費資源,於是我們就需要為表建立索引,索引的作用就是把表中的資料按照一定的順序排列儲存起來,於是就出現了乙個問題,有的表中的資料和索引想要排列的順序很是相近,而另一些表中的資料和索引想要排列的順序相距甚遠,聚簇因子的作用就是用來標示這個的,聚簇因子越小,相似度越高,聚簇因子越大,相似度越低。
我們知道了聚簇因子是幹嘛的了,但是還不了解標示資料的相似度有何意義,我們繼續討論:
oracle在儲存資料的時候,並不是按照資料塊的順序挨個進行存入資料,因為前面存入的資料經常會有dml或者ddl操作,刪除資料後,原先存有資料的資料塊就變成了空塊,oracle為了節省儲存空間,當資料庫再次有新資料進行插入的話,就會優先使用那些空塊,只有當空塊不夠使用的時候,才會去高水位以上開闢新塊,這種情況也就會導致,一張表中的資料,並不是儲存在相鄰的資料塊中,於是聚簇因子變的很大,當這種情況進行邏輯讀取的時候,就會增加io的次數,影響了讀取的速度。
既然說聚簇因子關係著表的讀取速度,那麼我們能夠手工控制聚簇因子的大小嗎?
答案是肯定的,但是事情總是有利也有弊,
1)我們可以對錶進行重構(alter table emp move);
2)或者按照索引的順序重建表(create table emp_bk as select * from emporder by empno);
3)可以在高水位以上開闢足夠的新塊,把一張表的資料全部存入這裡,以達到降低 聚簇因子的目的,但是帶來的結果也就是空間的浪費,同時因為高水位線是全表 掃瞄的終點,人為的拔高了水位線,容易造成全表掃的速率降低,因此需要慎重 考慮。
4)建立分割槽表,以減少對資料塊的訪問
實驗:
1
、準備試驗條件
--建立表
t_1 create
table
t_1 as
select
rownum rn,a.* from
all_objects a order
byobject_name desc;
--建立
t_1表關於
rownum
索引 create
index
ind_t_1 on
t_1(rn);
--建立表表
t_2 create
table
t_2 as
select
* from
( select
rownum rn,a.* from
all_objects a ) order
byrn asc;
--建立
t_2表關於
rownum
索引 create
index
ind_t_2 on
t_2(rn);
--分析兩張表及其索引
exec
dbms_stats.gather_table_stats(user, 't_1');
exec
dbms_stats.gather_table_stats(user, 't_2');
exec
dbms_stats.gather_index_stats(user, 'ind_t_1');
exec
dbms_stats.gather_index_stats(user, 'ind_t_2');
--說明:兩個表的區別就是
t_2表中的
rn是有序的,剛剛建立
t_2表的索引一致
2
、執行查詢操作
sql> set autot traceonly stat;
sql> select * from t_1 where rn between 100 and 120;
已選擇21行。
統計資訊
———————————————————-
0 recursive calls
0 db block gets
17 consistent gets
0 physical reads
0 redo size
1807 bytes sent via sql*net to client
357 bytes received via sql*net from client
3 sql*net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
21 rows processed
sql> select *from t_2 where rn between 100 and 120;
已選擇21行。
統計資訊
———————————————————-
0 recursive calls
0 db block gets
7 consistent gets
0 physical reads
0 redo size
1807 bytes sent via sql*net to client
357 bytes received via sql*net from client
3 sql*net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
21 rows processed
3
、觀察試驗結果
通過執行統計資訊觀察,
t_1表的查詢一致讀是
17,而
t_2表的一致讀只有
7,盡然
t_1的一致讀盡然是
t_2的
2倍還多,是不是有點奇怪,同樣的表結構,同樣的資料(
t_2多兩條資料)
4
、分析原因
通過查詢聚簇因子發現,兩個表的聚簇因子差別很大,基於
rn的索引在
rn是順序排列的表中,
clustering_factor
的值相差很大。
在表中資料有時候屬於無序狀態,這個時候的
clustering_factor
比較接近
num_rows
,說明如
果掃瞄整個表,每次都要根據
index
來讀取相應行的
rowid
,這個時候的
io操作很多,自然檢索時間會比較長。如果資料有序的
話,clustering_factor
比較接近
blocks
,說明相鄰的資料在乙個塊中,減少了
io運算元量,自然檢索時間會大大降低。
聚簇索引概念
聚簇索引與非聚簇索引 myisam與innodb引擎,索引檔案的異同 innodb的主索引檔案上 直接存放該行資料,稱為聚簇索引,次索引指向對主鍵的引用 myisam中,主索引和次索引,都指向物理行 磁碟位置 注意 innodb來說,1 主鍵索引 既儲存索引值,又在葉子中儲存行的資料 2 如果沒有主...
聚簇索引概念
聚簇索引與非聚簇索引 myisam與innodb引擎,索引檔案的異同 innodb的主索引檔案上 直接存放該行資料,稱為聚簇索引,次索引指向對主鍵的引用 myisam中,主索引和次索引,都指向物理行 磁碟位置 注意 innodb來說,1 主鍵索引 既儲存索引值,又在葉子中儲存行的資料 2 如果沒有主...
oracle聚簇索引
很多初學者,在接觸oracle資料庫後,都會很疑惑oracle聚簇索引是什麼,如何使用oracle聚簇索引,oracle雜湊聚簇又與oracle聚簇索引有什麼關係。本文針對這3個問題結合相關資料,給出了點看法。1.什麼是聚簇 聚簇是根據碼值找到資料的物理儲存位置,從而達到快速檢索資料的目的。orac...