聚簇表簡介
聚簇原理:
聚簇是指:如果一組表有一些共同的列,則將這樣一組表儲存在相同的資料庫塊中;聚簇還表示把相關的資料儲存在同一個塊上。利用聚簇,
一個塊可能包含多個表的資料。概念上就是如果兩個或多個表經常做連結操作,那麼可以把需要的資料預先儲存在一起。聚簇還可以用於單個表,
可以按某個列將資料分組儲存。
更加簡單的說,比如說,EMP表和DEPT表,這兩個表儲存在不同的segment中,甚至有可能儲存在不同的TABLESPACE中,因此,他們的資料一定不會
在同一個BLOCK裡。而我們有會經常對這兩個表做關聯查詢,比如說:select * from emp,dept where emp.deptno = dept.deptno .仔細想想,查詢
主要是對BLOCK的操作,查詢的BLOCK越多,系統IO就消耗越大。如果我把這兩個表的資料聚集在少量的BLOCK裡,查詢效率一定會提高不少。
比如我現在將值deptno=10的所有員工抽取出來,並且把對應的部門資訊也儲存在這個BLOCK裡(如果存不下了,可以為原來的塊串聯另外的塊)。
這就是索引聚簇表的工作原理。
聚簇的具體使用:
--建立聚簇
create cluster emp_dept_cluster ( deptno number(2) )size 1024;
--建立聚簇索引
create index emp_dept_cluster_idx on cluster emp_dept_cluster;
--建立聚簇索引表(dept)
create table dept
( deptno number(2) primary key, dname varchar2(14),loc varchar2(13)) cluster emp_dept_cluster(deptno);
--建立聚簇索引表(emp)
create table emp
( empno number primary key,ename varchar2(10),job varchar2(9),mgr number,hiredate date,sal number,comm number,
deptno number(2) constraint emp_fk references dept(deptno)) cluster emp_dept_cluster(deptno);
--檢視建立的聚簇索引表
select cluster_name, table_name from user_tables where cluster_name is not null order by 1;
--載入資料前必須先建立聚簇索引,否則會提示“ORA-02032:聚簇表無法在簇索引建立之前使用”
begin
for x in (select * from dept) loop
insert into dept values (x.deptno, x.dname, x.loc);
insert into emp
select * from emp where deptno = x.deptno;
end loop;
end;
--取消外來鍵
alter table emp disable constraint emp_fk;
--截斷簇(在截斷簇之前必須先關閉外來鍵引用,否則提示“ORA-02266:表中的唯一/主鍵被啟用的外來鍵引用”)
truncate cluster emp_dept_cluster;
--啟用外來鍵
alter table emp enable constraint emp_fk;
/*增加一個很大的列char(1000),加這個列是為了讓EMP行遠遠大於現在的大小。使得一個1024的聚簇無法儲存一行記錄。不能加 varchar2(1000),
因為ORACLE對varchar2儲存的原則是能省就省,如果資料資料不到1000,不會分配1000的空間。 char則是分配多少用多少*/
alter table emp add data char(1000);
--第一種方式插入資料
insert into dept select * from lttfm.dept;
insert into emp select emp.*,'*'from lttfm.emp;
--有兩條記錄兩個表的塊不同
select dept_blk,
emp_blk,
case
when dept_blk <> emp_blk then
'*'
end flag,--如果兩個表的塊不同則用*表示
deptno
from (select dbms_rowid.rowid_block_number(dept.rowid) dept_blk,
dbms_rowid.rowid_block_number(emp.rowid) emp_blk,
dept.deptno
from emp, dept
where emp.deptno = dept.deptno)
order by deptno;
--第二種方式插入資料
begin
for x in (select * from lttfm.dept) loop
insert into dept values (x.deptno, x.dname, x.loc);
insert into emp
select emp.*, 'x' from lttfm.emp where deptno = x.deptno;
end loop;
end;
--再次檢視(兩個表的塊基本相同)
select dept_blk,
emp_blk,
case
when dept_blk <> emp_blk then
'*'
end flag,
deptno
from (select dbms_rowid.rowid_block_number(dept.rowid) dept_blk,
dbms_rowid.rowid_block_number(emp.rowid) emp_blk,
dept.deptno
from emp, dept
where emp.deptno = dept.deptno)
order by deptno;
注:插入資料之前先做截斷簇
聚簇是指:如果一組表有一些共同的列,則將這樣一組表儲存在相同的資料庫塊中;聚簇還表示把相關的資料儲存在同一個塊上。利用聚簇,
一個塊可能包含多個表的資料。概念上就是如果兩個或多個表經常做連結操作,那麼可以把需要的資料預先儲存在一起。聚簇還可以用於單個表,
可以按某個列將資料分組儲存。
更加簡單的說,比如說,EMP表和DEPT表,這兩個表儲存在不同的segment中,甚至有可能儲存在不同的TABLESPACE中,因此,他們的資料一定不會
在同一個BLOCK裡。而我們有會經常對這兩個表做關聯查詢,比如說:select * from emp,dept where emp.deptno = dept.deptno .仔細想想,查詢
主要是對BLOCK的操作,查詢的BLOCK越多,系統IO就消耗越大。如果我把這兩個表的資料聚集在少量的BLOCK裡,查詢效率一定會提高不少。
比如我現在將值deptno=10的所有員工抽取出來,並且把對應的部門資訊也儲存在這個BLOCK裡(如果存不下了,可以為原來的塊串聯另外的塊)。
這就是索引聚簇表的工作原理。
聚簇的具體使用:
--建立聚簇
create cluster emp_dept_cluster ( deptno number(2) )size 1024;
--建立聚簇索引
create index emp_dept_cluster_idx on cluster emp_dept_cluster;
--建立聚簇索引表(dept)
create table dept
( deptno number(2) primary key, dname varchar2(14),loc varchar2(13)) cluster emp_dept_cluster(deptno);
--建立聚簇索引表(emp)
create table emp
( empno number primary key,ename varchar2(10),job varchar2(9),mgr number,hiredate date,sal number,comm number,
deptno number(2) constraint emp_fk references dept(deptno)) cluster emp_dept_cluster(deptno);
--檢視建立的聚簇索引表
select cluster_name, table_name from user_tables where cluster_name is not null order by 1;
--載入資料前必須先建立聚簇索引,否則會提示“ORA-02032:聚簇表無法在簇索引建立之前使用”
begin
for x in (select * from dept) loop
insert into dept values (x.deptno, x.dname, x.loc);
insert into emp
select * from emp where deptno = x.deptno;
end loop;
end;
--取消外來鍵
alter table emp disable constraint emp_fk;
--截斷簇(在截斷簇之前必須先關閉外來鍵引用,否則提示“ORA-02266:表中的唯一/主鍵被啟用的外來鍵引用”)
truncate cluster emp_dept_cluster;
--啟用外來鍵
alter table emp enable constraint emp_fk;
/*增加一個很大的列char(1000),加這個列是為了讓EMP行遠遠大於現在的大小。使得一個1024的聚簇無法儲存一行記錄。不能加 varchar2(1000),
因為ORACLE對varchar2儲存的原則是能省就省,如果資料資料不到1000,不會分配1000的空間。 char則是分配多少用多少*/
alter table emp add data char(1000);
--第一種方式插入資料
insert into dept select * from lttfm.dept;
insert into emp select emp.*,'*'from lttfm.emp;
--有兩條記錄兩個表的塊不同
select dept_blk,
emp_blk,
case
when dept_blk <> emp_blk then
'*'
end flag,--如果兩個表的塊不同則用*表示
deptno
from (select dbms_rowid.rowid_block_number(dept.rowid) dept_blk,
dbms_rowid.rowid_block_number(emp.rowid) emp_blk,
dept.deptno
from emp, dept
where emp.deptno = dept.deptno)
order by deptno;
--第二種方式插入資料
begin
for x in (select * from lttfm.dept) loop
insert into dept values (x.deptno, x.dname, x.loc);
insert into emp
select emp.*, 'x' from lttfm.emp where deptno = x.deptno;
end loop;
end;
--再次檢視(兩個表的塊基本相同)
select dept_blk,
emp_blk,
case
when dept_blk <> emp_blk then
'*'
end flag,
deptno
from (select dbms_rowid.rowid_block_number(dept.rowid) dept_blk,
dbms_rowid.rowid_block_number(emp.rowid) emp_blk,
dept.deptno
from emp, dept
where emp.deptno = dept.deptno)
order by deptno;
注:插入資料之前先做截斷簇
總結:
當我們通過第一種方法時,有一個問題,由於dept表的行在聚簇中佔用空間很小,但是剩餘的空間確不能存一條dept的資料(應為我們新增了
char(1000)了)。這樣就會在那些聚簇 鍵塊上導致過度的串鏈。Oracle會把包含這些資訊的一組塊串鏈或連結起來。但是如第二種方法一樣,如果同時
載入對應一個給定聚簇鍵的所有資料,就能儘可能緊地塞滿塊,等空間用完時再開始一個新塊。
什麼時候不應該使用聚簇?
1) 如果預料到聚簇中的表會大量修改:必須知道,索引聚簇會對DML的效能產生某種負面影響(特別是INSERT語句)。管理聚簇中的資料需要做更多的
工作。
2) 如果需要對聚簇中的表執行全表掃描:不只是必須對你的表中的資料執行全面掃描,還必須對(可能的)多個表中的資料進行全面掃描。由於需要
掃描更多的資料,所以全表掃描耗時更久。
3) 如果你認為需要頻繁地TRUNCATE和載入表:聚簇中的表不能截除。這是顯然的,因為聚簇在一個塊上儲存了多個表,必須刪除聚簇表中的行。
因此,如果資料主要用於讀(這並不表示“從來不寫”;聚簇表完全可以修改),而且要通過索引來讀(可以是聚簇鍵索引,也可以是聚簇表上的其他索引)
,另外會頻繁地把這些資訊聯結在一起,此時聚簇就很適合。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29144194/viewspace-1167286/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle聚簇表Oracle
- 資料庫表,索引(索引組織表,聚簇表,聚簇索引,)資料庫索引
- 【實驗】【聚簇】聚簇(Cluster)和聚簇表(Cluster Table)的建立與總結
- oracle 聚簇表學習Oracle
- 淺談聚簇索引與非聚簇索引索引
- 聚簇索引索引
- MySQL中的聚簇索引和非聚簇索引MySql索引
- MySQL聚簇索引和非聚簇索引的原理及使用MySql索引
- 一分鐘明白MySQL聚簇索引和非聚簇索引MySql索引
- 聚簇因子的理解
- 聚簇索引和非聚簇索引到底有什麼區別?索引
- 聊聊Oracle聚簇Cluster(上)Oracle
- ORACLE 聚簇因子優化Oracle優化
- Oracle的簇與簇表Oracle
- 簇表及簇表管理(Index clustered tables)Index
- 一看就懂的MySQL的聚簇索引,以及聚簇索引是如何長高的MySql索引
- InnoDB學習(八)之 聚簇索引索引
- MySQL 聚簇索引 和覆蓋索引MySql索引
- 一次簡單的效能優化診斷,聚簇因子過高導致全表掃描。優化
- 資料庫聚簇索引——not null條件對唯一鍵索引成為聚簇索引的影響資料庫索引Null
- k-均值聚類簡介聚類
- MySQL 聚簇索引一定是主鍵嗎MySql索引
- MySQL innodb如何選擇一個聚簇索引MySql索引
- 聚簇因子和執行計劃的聯絡
- 淺談索引系列之聚簇因子(clustering_factor)索引
- clustering factor索引聚簇因子和執行計劃索引
- 【Mysql】InnoDB 中的聚簇索引、二級索引、聯合索引MySql索引
- 理解索引和聚簇——效能調整手冊和參考索引
- 什麼是Oracle簇(CLUSTER)表Oracle
- 一篇文章講清楚MySQL的聚簇/聯合/覆蓋索引、回表、索引下推MySql索引
- oracle cluster(簇)的簡單使用Oracle
- [MySQL]為什麼非聚簇索引不儲存資料位置MySql索引
- Foundation 價格表簡介
- ORACLE temp表的簡介Oracle
- 活動內碼表簡介
- 部分聚類演算法簡介及優缺點分析聚類演算法
- 表單Form簡介——表單按鈕ORM
- 表單驗證教程簡介