Oracle 聚簇因子概念及實驗

2021-07-09 16:24:59 字數 4050 閱讀 1501

**:

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...