索引聚簇:將一組表中相同列存放在相同數據塊上,就是把相關數據存放在一起。
create cluster cluster_emp_dept(no number ) size 1024;---創建簇 size就是確定一個cluster鍵佔用多少空間。
create index cluster_emp_dept_inx on cluster cluster_emp_dept ;--創建聚簇索引 這個索引必須在插入數據前創建
create table emp(name varchar2(100),deptno number) cluster cluster_emp_dept(deptno);
create table dept(name varchar2(100),no number)cluster cluster_emp_dept(no);
insert into emp (name ,deptno)values('1',1);
insert into dept (name ,no)values('1',1);
通過視圖查詢
select * from all_objects t where t.data_object_id=(select distinct dbms_rowid.rowid_object(rowid) from emp)
select rowid from emp;
select rowid from dept;
會發現rowid是一樣
查看相同no是不是在一個塊裏面
select dbms_rowid.rowid_block_number(t.rowid),dbms_rowid.rowid_block_number(t1.rowid)
from dept t, emp t1 where t.no=t1.deptno;
查看size 1024 作用
truncate cluster cluster_emp_dept;刪除emp和dept所有數據HWM爲0
添加8(1024×8=db_block_size 因爲其他需要佔用一部分空間 所以需要兩個塊)條
begin
for i in 1..8 loop
insert into emp (name ,deptno)values(''||i,i);
insert into dept (name ,no)values(''||i,i);
end loop;
end;
select dbms_rowid.rowid_block_number(t.rowid),dbms_rowid.rowid_block_number(t1.rowid)
from dept t, emp t1 where t.no=t1.deptno;
剛好第八行存入另一個塊中
索引聚簇表特點:
1、索引聚簇表的DML操作時間長,管理數據需要許多操作。
2、對索引聚簇表進行全表掃描時,需要注意的是不僅僅是掃描該表,還要掃描多張表。但表掃描時間長。
3、索引聚簇中的表和索引聚簇不能分區。
4、索引聚簇上的表不能truncate table 但是可以truncate cluster
5、如果索引聚簇表之間通過據簇鍵關聯,這時性能非常好,較少oracle緩存塊個數
缺點:需要精確計算size參數,太大導致空間浪費。太小導致行遷移
創建時間長:需要分配大量空間,初始表所佔用空間大,從而導致管理複雜
全表掃面時,因爲都分配了空間,所有初始空間在HWM之下,所以掃描量非常大(聚簇是爲了據簇鍵快速找到數據,不是爲了全表掃描)
另一種聚簇表——哈希聚簇表,聚簇鍵值是指定聚簇字段值的哈希值。分配空間情況是:hashkeys/(trunc(blocksize/size))
create cluster cluster_hash_emp_dept(no number) hashkeys 1000 size 1024;
-- Create table
create table EMP1
(
NAME VARCHAR2(100),
DEPTNO NUMBER
)
cluster cluster_hash_emp_dept (DEPTNO);
-- Create table
create table DEPT1
(
NAME VARCHAR2(100),
NO NUMBER
)
cluster cluster_hash_emp_dept (NO);
begin
for i in 1..10 loop
insert into EMP1 values(''||i,i);
insert into DEPT1 values(''||i,i);
end loop;
commit;
end;
在hashkeys值選擇方面,oracle會根據一個最接近於hashkeys大於等於質數,所以1000的最接近的質數是1009,它所需的最小初始數據塊數爲1009/(8192/1024)
使用hash聚簇,當你插入第1010個部門時,會導致hash鍵值衝突(兩個hash值一樣,要儘量避免衝突,因爲它增加了開銷,使得塊串聯的可能性增加),hash聚簇最大優點是等值查找
HASH TABLE小結
1) 散列聚簇一開始就要分配空間。Oracle根據你的HASHKEYS和SIZE來計算HASHKEYS/trunc
(blocksize/SIZE),立即分配空間,並完成格式化,一旦將第一個表放入這個聚簇中,任何
全面掃描都會命中每一個已分配的塊。在這方面,它與其他的所有表都不同。
2) 散列聚簇中的HASHKEY 數是固定大小的。除非重新聚簇,否則不能改變散列表的大小。這
並不會限制聚簇中能存儲的數據量,它只是限制了能爲這個聚簇生成的惟一散列鍵的個數。如
果HASHKEY 值設置得太低,可能因爲無意的散列衝突影響性能。
3) 不能在聚簇鍵上完成區間掃描。諸如WHERE cluster_key BETWEEN 50 AND 60 謂詞條件
不能使用散列算法。介於50~60 之間的可能值有無限多個,服務器必鬚生成所有可能的值,並
分別計算散列,來查看相應位置是否有數據。這是不可能的。如果你在一個聚簇鍵上使用區間
掃描,而且沒有使用傳統索引,實際上會全面掃描這個聚簇。
HASHED TABLE的要點是:
1)HASHED TABLE中是把傳遞到查詢的需求轉換成一個FILE/BLOCK,並且直接讀,不經過索引.
2)HASHED TABLE的I/O要少得多,因爲heap table要至少做一次I/O來獲取rowid,然後通過rowid來訪問表,前者訪問緩存次數是後者的1/3
3)散列聚簇查詢與索引查詢所用的CPU是一樣的,儘管它訪問buffer hash的次數要少得多
但執行hash是一個CPU相當密集的操作(索引是I/O密集的操作).這裏要做個權衡.
單表散列據簇表
create cluster cluster_single ( no number) hashkeys 1000 size 1024 single table;
create table cluster_single_table_emp( no number,name varchar2(200)) cluster cluster_single(no);
單表散列聚簇表能夠更快的結束數據查詢,更少的latch鎖
有序散列聚簇表
create cluster cluster_single ( no number,dt datetime sort) hashkeys 1000 size 1024 hash is no ;
create table cluster_single_table_emp( no number,name varchar2(200),dt datetime sort) cluster cluster_single(no);