我們在查詢索引狀態的時候,通常會用到user_indexes這張表,這張表中有一列(CLUSTERING_FACTOR 聚簇因子),這裡簡單的介紹下聚簇因子的意思,大家知道資料表中的資料都是無序的存在庫中,當我們在對資料進行檢索的時候,尋找起來很是耗費資源,於是我們就需要為表建立索引,索引的作用就是把表中的資料按照一定的順序排列儲存起來,於是就出現了一個問題,有的表中的資料和索引想要排列的順序很是相近,而另一些表中的資料和索引想要排列的順序相距甚遠,聚簇因子的作用就是用來標示這個的,聚簇因子越小,相似性越高,聚簇因子越大,相似性越低。
我們知道了聚簇因子是幹嘛的了,但是還不瞭解標示資料的相似性有何意義,我們繼續討論:
oracle在儲存資料的時候,並不是按照資料區塊的順序挨個進行存入資料,因為前面存入的資料經常會有dml或者ddl操作,刪除資料後,原先存有資料的資料區塊就變成了空塊,oracle為了節省儲存空間,當資料庫再次有新資料進行插入的話,就會優先使用那些空塊,只有當空塊不夠使用的時候,才會去高水位以上開闢新塊,這種情況也就會導致,一張表中的資料,並不是儲存在相鄰的資料區塊中,於是聚簇因子變的很大,當這種情況進行邏輯讀取的時候,就會增加IO的次數,影響了讀取的速度。
既然說聚簇因子關係著表的讀取速度,那麼我們能夠手工控制聚簇因子的大小嗎。
答案是肯定的,但是事情總是有利也有弊,
1)我們可以對錶進行重構(alter table emp move);
2)或者按照索引的順序重建表(create table emp_bk as select * from emp order by empno);
3)可以在高水位以上開闢足夠的新塊,把一張表的資料全部存入這裡,以達到降低 聚簇因子的目的,但是帶來的結果也就是空間的浪費,同時因為高水位線是全表 掃描的終點,人為的拔高了水位線,容易造成全表掃的速率降低,因此需要謹慎 考慮。
4)建立分區表,以減少對資料區塊的訪問
例如 emp表中,僱員共分3個部門(deptno:10,20,30),我們按照部門號進行分區:
create table EMP
(
empno NUMBER(4) not null,
ename VARCHAR2(10),
job VARCHAR2(9),
mgr NUMBER(4),
hiredate DATE,
sal NUMBER(7,2),
comm NUMBER(7,2),
deptno NUMBER(2)
)
partition by list(deptno)
(partition dept_10 values(10),
partition dept_20 values(20),
partition dept_30 values(30),
partition dept_other values(default));
當我們執行 select * from emp where deptno=10; 時,oracle會將不屬於10分區的其他分區,全部剔除出去,只訪問10部門分區。
查看10部分分區:select * from emp partition(dept_10);