Oracle 原理:高水位線、PCTFREE、PCTUSED、索引組織表、簇表、臨時表

目錄

1.11g中表的類型:

2.高水位線HWM,(High Water Mark)

3.PCTFREE 和PCTUSED;

4. move、shrink、truncate來降低高水位線

5.IOT表、簇表、臨時表


1.11g中表的類型:

普通表、分區表、索引組織表IOT、簇表、臨時表、嵌套表、對象表等。

分區表:爲了提高容納的數據量和查詢速度把一個表分在多個區上。簇表:使聯合查詢時變得快。適用於頻繁關聯查詢的表。嵌套表:表中有表,比如的表A中某行某列是表B的數據,像"盒子"一樣的包含關係,就叫嵌套表。

2.高水位線HWM,(High Water Mark)

高水位線是指的是在 表中數據塊的歷史最大使用數量。高水位線一般是不會降低的。除非使用rebuild重建,truncated截斷,shrunk收縮纔會刷新高水位線。 

  全表掃描時,就是從表中的第0個數據塊開始,一個數據塊一個數據塊的掃描到高水位線。也就是說,如果表中沒有任何數據,也會要掃描到高水位線的數據塊位置。

剛開始創建表是高水位線位於0號數據塊位置,然後不斷地插入數據,高水位線因此上升,然後把數據刪除,高水位線依舊不變,如上圖。

3.PCTFREE 和PCTUSED;

一個數據塊大小默認爲8KB,而PCTFREE(默認10%)指定了一個數據塊中插入數據允許的最小空閒內存佔比。而PCTUSED(默認40%)指定了一個數據塊中允許重新插入數據的內存佔比,單位爲%。當往表中插入數據時,不會把數據塊放滿,因爲這個空閒內存是爲了給修改數據做準備的。加入insert數據塊把數據塊放滿了後,再update數據內容,內容減小還好說,內容變多,當前數據塊就沒有可用的內存來給數據擴展了。數據塊包含了3部分:數據塊頭(Header)、空閒內存(Free Space)、數據(DATA); PCTFREE控制着Free Space的最小值,超過則不準再插入,允許刪除。PCTUSED控制着DATA的最小值,超過則恢復允許插入。不是說PCTFREE設了20%空間區域就永遠大於20%,而是說空閒區域至少留20%將來給Oracle做數據擴展用的。一個數據塊可以放表中的多個行數據。

 結合上圖所示。當一個數據塊被啓用時,數據塊使用率從0%開始上升,未使用率從100%開始下降。假如PCTFREE設成20%,PCTUSED設成40%。由於剛開始數據塊的使用率小於PCTUSED,所以允許往數據塊中插入數據,直到未使用率達到FreeSpace變成了20%就不準在往此數據塊中插入數據了,想要再往這個數據塊中插入數據,就要把數據塊使用率下降到PCTUSED 40%才被允許。

如果數據依舊超出了數據塊總大小,將用行遷移的方式:Oracle會把原來數據塊上的行數據頭(Row-Header)保留,後面跟個C++一樣的指針,把數據Data遷移到新的數據塊上,讓指針指向這數據。

數據塊大小默認 8KB ,如果一個數據行大小超出了內存中最大可用的數據塊大小,將會發生行鏈接:將一筆數據放入不同的數據塊中,用指針的方式將同一筆數據關聯起來。

 

如果表空間上指定了ASSM時,建表時只能指定PCTFREE。ASSM,自動段空間管理。MSSM,手動段空間管理。

查看是否段空間管理: select s.TABLESPACE_NAME,s.SEGMENT_SPACE_MANAGEMENT from dba_tablespaces s;

表空間擴展:alter table voapd.t1 allocate extent(datafile 'D:\ORACLE\ORADATA\ORCL\TESTTBS.DBF' size 1m);

4. move、shrink、truncate來降低高水位線

  move 語句,將表中的數據移動到另一個表空間上,同時會清除表空間碎片和降低高水位線:

  alter table [表名] move [tablespace USERS];

爲了理解高水位線,首先創建一張表t2:

------之前創建了表空間 TESTTBS;
create table t2 tablespace TESTTBS as select * from dba_objects; --count(*)=72092

之後可以分析表中多少數據塊

analyze table t2 compute statistics for table;
select table_name,blocks,num_rows from user_tables where table_name='T2';

然後再刪除t2 數據表中3萬行數據:

delete t2 where rownum < 30000;
commit;
analyze table t2 compute statistics for table;
select table_name,blocks,num_rows from user_tables where table_name='T2';

可以發現,數據行少了3萬,但是佔用的數據塊卻是沒有變的。

用move對錶的高水位線進行調整: 

alter table t2 move tablespace USERS;
analyze table t2 compute statistics for table;
select table_name,blocks,num_rows from user_tables where table_name='T2';

可以看出,T2表中的高水位線被刷新了。但是使用move之時,表不能有其他應用,同時表上的索引也要重新建立。

 

用Shrink語句收縮表,將數據行的數據塊移動到另外一個數據塊上,是數據收縮,收縮完後降低高水位線。收縮時可以DML操作(增刪改),降低高水位線時不準DML操作。使用Shrink語句的前提是:表所在的表空間啓用了ASSM自動段管理,表上也啓用了ROW MOVEMENT

select s.TABLESPACE_NAME,s.SEGMENT_SPACE_MANAGEMENT from dba_tablespaces s
select table_name,u.ROW_MOVEMENT from user_tables u where table_name='T2';
alter table t2 enable row movement;
alter table t2 shrink space;
analyze table t2 compute statistics for table;
select table_name,blocks,num_rows from user_tables where table_name='T2';
---

truncate table [表名]:保留表結構刪除所有表數據,無法回滾。這個操作也可以把HWM降到最低。

 

當數據量過多時,刪除表結構的速度會非常慢:可以先把改列設成unused,再把unused 的列給刪除,這樣刪除列的操作就會在數據庫空閒的時候自動完成。

alter table [表名] set unused column [列名];      alter table t2 drop unused columns;

5.IOT表、簇表、臨時表

IOT 索引組織表:這個表必須有主鍵,會自動地按照主鍵進行排序,是個有序的表。與普通表不同,普通表和表主鍵上的索引都會需要爲它們留出存儲空間,而IOT不存在主鍵的空間開銷。索引(主鍵)是存放在一起的;數據存儲在索引塊中;所以經常通過主鍵來訪問數據的話,IOT表更適合;

create table student_iot(
 sno int,
 sname varchar2(20),
 sage int , 
 constraints pk_student primary key(sno)
)
organization index    
pctthreshold 30 overflow tablespace users; --指定閾值30%,當一行記錄太大超出了數據索引塊的30%,其他列(sname 、sage)就會放到指定的表空間裏users

刪除索引表的溢出表,首先要先刪除索引表,然後清空回收站,命令 : purge recyclebin;

 

簇表:兩個相互關聯的表數據,同時放到一個數據塊中。這樣關聯查詢時,就只有掃描1個數據塊就行。

創建簇表步驟如下:簇的數據類型要和表字段的數據類型一致。

----1.創建簇-----
create cluster cluster1(ckey int);
----2.創建表時關聯簇---------
create table student_cluster(
 sno int ,
 sname varchar2(20),
 sage int )
 cluster cluster1(sno);
----3.創建另一張表時關聯簇---------
create table record_cluster(
 sno int ,
 record int )
 cluster cluster1(sno);
----4.簇上要建立索引-------
 create index index1 on cluster cluster1;


select * from user_clusters;  --查詢簇的信息
 select * from user_clu_columns;  --查詢簇的關聯信息

----------5刪除簇要先把簇表刪除-----------
 drop table student_cluster;
 drop table record_cluster;
 drop cluster cluster1;

臨時表:臨時表的創建必定在臨時表空間 TEMP,臨時表數據只能在同一個session中看到,數據不被不同session所共享。每個session的臨時表中的數據是完全獨立的;

創建臨時表語法如下:

create global temporary table student_temp(
 sno int ,
 sname varchar2(20),
 sage int ) 
 --on commit delete rows --(默認值);
 on commit preserve rows;

其中 on commit delete rows; 指明瞭當事物提交或回滾時,自動把臨時表數據清除; on commit Preserve rows 指明瞭當Session 斷開和數據庫連接時纔會刪除臨時表中的數據;

由圖可以知道,兩個Session 中的臨時表是完全獨立的,互不干擾,儘管用戶都是相同的。指定 on commit preserve rows;的臨時表 ,其中的數據不會因爲commit而被清空。然而用戶斷開連接時,臨時表中數據纔會刪除。

drop 掉臨時表的前提是,所有使用這臨時表的session中表內不準有數據。

當採用on commit delete rows創建臨時表時,一提交數據,表中的數據就被清空

查詢臨時表信息:

 select u.TABLE_NAME as 表名,
 u.TEMPORARY as 是否是臨時表,
 u.DURATION as 是否是事務型的建表方式
  from user_tables u  where  u.TABLE_NAME='STUDENT_TEMP';

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章