Oracle 原理:高水位线、PCTFREE、PCTUSED、索引组织表、簇表、临时表
目錄
1.11g中表的類(lèi)型:
2.高水位線(xiàn)HWM,(High Water Mark)
3.PCTFREE 和PCTUSED;
4. move、shrink、truncate來(lái)降低高水位線(xiàn)
5.IOT表、簇表、臨時(shí)表
1.11g中表的類(lèi)型:
普通表、分區(qū)表、索引組織表IOT、簇表、臨時(shí)表、嵌套表、對(duì)象表等。
分區(qū)表:為了提高容納的數(shù)據(jù)量和查詢(xún)速度把一個(gè)表分在多個(gè)區(qū)上。簇表:使聯(lián)合查詢(xún)時(shí)變得快。適用于頻繁關(guān)聯(lián)查詢(xún)的表。嵌套表:表中有表,比如的表A中某行某列是表B的數(shù)據(jù),像"盒子"一樣的包含關(guān)系,就叫嵌套表。
2.高水位線(xiàn)HWM,(High Water Mark)
高水位線(xiàn)是指的是在 表中數(shù)據(jù)塊的歷史最大使用數(shù)量。高水位線(xiàn)一般是不會(huì)降低的。除非使用rebuild重建,truncated截?cái)?shrunk收縮才會(huì)刷新高水位線(xiàn)。?
? 全表掃描時(shí),就是從表中的第0個(gè)數(shù)據(jù)塊開(kāi)始,一個(gè)數(shù)據(jù)塊一個(gè)數(shù)據(jù)塊的掃描到高水位線(xiàn)。也就是說(shuō),如果表中沒(méi)有任何數(shù)據(jù),也會(huì)要掃描到高水位線(xiàn)的數(shù)據(jù)塊位置。
剛開(kāi)始創(chuàng)建表是高水位線(xiàn)位于0號(hào)數(shù)據(jù)塊位置,然后不斷地插入數(shù)據(jù),高水位線(xiàn)因此上升,然后把數(shù)據(jù)刪除,高水位線(xiàn)依舊不變,如上圖。
3.PCTFREE 和PCTUSED;
一個(gè)數(shù)據(jù)塊大小默認(rèn)為8KB,而PCTFREE(默認(rèn)10%)指定了一個(gè)數(shù)據(jù)塊中插入數(shù)據(jù)允許的最小空閑內(nèi)存占比。而PCTUSED(默認(rèn)40%)指定了一個(gè)數(shù)據(jù)塊中允許重新插入數(shù)據(jù)的內(nèi)存占比,單位為%。當(dāng)往表中插入數(shù)據(jù)時(shí),不會(huì)把數(shù)據(jù)塊放滿(mǎn),因?yàn)檫@個(gè)空閑內(nèi)存是為了給修改數(shù)據(jù)做準(zhǔn)備的。加入insert數(shù)據(jù)塊把數(shù)據(jù)塊放滿(mǎn)了后,再u(mài)pdate數(shù)據(jù)內(nèi)容,內(nèi)容減小還好說(shuō),內(nèi)容變多,當(dāng)前數(shù)據(jù)塊就沒(méi)有可用的內(nèi)存來(lái)給數(shù)據(jù)擴(kuò)展了。數(shù)據(jù)塊包含了3部分:數(shù)據(jù)塊頭(Header)、空閑內(nèi)存(Free Space)、數(shù)據(jù)(DATA);?PCTFREE控制著Free Space的最小值,超過(guò)則不準(zhǔn)再插入,允許刪除。PCTUSED控制著DATA的最小值,超過(guò)則恢復(fù)允許插入。不是說(shuō)PCTFREE設(shè)了20%空間區(qū)域就永遠(yuǎn)大于20%,而是說(shuō)空閑區(qū)域至少留20%將來(lái)給Oracle做數(shù)據(jù)擴(kuò)展用的。一個(gè)數(shù)據(jù)塊可以放表中的多個(gè)行數(shù)據(jù)。
?結(jié)合上圖所示。當(dāng)一個(gè)數(shù)據(jù)塊被啟用時(shí),數(shù)據(jù)塊使用率從0%開(kāi)始上升,未使用率從100%開(kāi)始下降。假如PCTFREE設(shè)成20%,PCTUSED設(shè)成40%。由于剛開(kāi)始數(shù)據(jù)塊的使用率小于PCTUSED,所以允許往數(shù)據(jù)塊中插入數(shù)據(jù),直到未使用率達(dá)到FreeSpace變成了20%就不準(zhǔn)在往此數(shù)據(jù)塊中插入數(shù)據(jù)了,想要再往這個(gè)數(shù)據(jù)塊中插入數(shù)據(jù),就要把數(shù)據(jù)塊使用率下降到PCTUSED 40%才被允許。
如果數(shù)據(jù)依舊超出了數(shù)據(jù)塊總大小,將用行遷移的方式:Oracle會(huì)把原來(lái)數(shù)據(jù)塊上的行數(shù)據(jù)頭(Row-Header)保留,后面跟個(gè)C++一樣的指針,把數(shù)據(jù)Data遷移到新的數(shù)據(jù)塊上,讓指針指向這數(shù)據(jù)。
數(shù)據(jù)塊大小默認(rèn) 8KB ,如果一個(gè)數(shù)據(jù)行大小超出了內(nèi)存中最大可用的數(shù)據(jù)塊大小,將會(huì)發(fā)生行鏈接:將一筆數(shù)據(jù)放入不同的數(shù)據(jù)塊中,用指針的方式將同一筆數(shù)據(jù)關(guān)聯(lián)起來(lái)。
?
如果表空間上指定了ASSM時(shí),建表時(shí)只能指定PCTFREE。ASSM,自動(dòng)段空間管理。MSSM,手動(dòng)段空間管理。
查看是否段空間管理: select s.TABLESPACE_NAME,s.SEGMENT_SPACE_MANAGEMENT from dba_tablespaces s;
表空間擴(kuò)展:alter table voapd.t1 allocate extent(datafile 'D:\ORACLE\ORADATA\ORCL\TESTTBS.DBF' size 1m);
4. move、shrink、truncate來(lái)降低高水位線(xiàn)
? move 語(yǔ)句,將表中的數(shù)據(jù)移動(dòng)到另一個(gè)表空間上,同時(shí)會(huì)清除表空間碎片和降低高水位線(xiàn):
? alter table [表名] move [tablespace USERS];
為了理解高水位線(xiàn),首先創(chuàng)建一張表t2:
------之前創(chuàng)建了表空間 TESTTBS; create table t2 tablespace TESTTBS as select * from dba_objects; --count(*)=72092之后可以分析表中多少數(shù)據(jù)塊
analyze table t2 compute statistics for table; select table_name,blocks,num_rows from user_tables where table_name='T2';然后再刪除t2 數(shù)據(jù)表中3萬(wàn)行數(shù)據(jù):
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';可以發(fā)現(xiàn),數(shù)據(jù)行少了3萬(wàn),但是占用的數(shù)據(jù)塊卻是沒(méi)有變的。
用move對(duì)表的高水位線(xiàn)進(jìn)行調(diào)整:?
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表中的高水位線(xiàn)被刷新了。但是使用move之時(shí),表不能有其他應(yīng)用,同時(shí)表上的索引也要重新建立。
?
用Shrink語(yǔ)句收縮表,將數(shù)據(jù)行的數(shù)據(jù)塊移動(dòng)到另外一個(gè)數(shù)據(jù)塊上,是數(shù)據(jù)收縮,收縮完后降低高水位線(xiàn)。收縮時(shí)可以DML操作(增刪改),降低高水位線(xiàn)時(shí)不準(zhǔn)DML操作。使用Shrink語(yǔ)句的前提是:表所在的表空間啟用了ASSM自動(dòng)段管理,表上也啟用了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 [表名]:保留表結(jié)構(gòu)刪除所有表數(shù)據(jù),無(wú)法回滾。這個(gè)操作也可以把HWM降到最低。
?
當(dāng)數(shù)據(jù)量過(guò)多時(shí),刪除表結(jié)構(gòu)的速度會(huì)非常慢:可以先把改列設(shè)成unused,再把unused 的列給刪除,這樣刪除列的操作就會(huì)在數(shù)據(jù)庫(kù)空閑的時(shí)候自動(dòng)完成。
alter table [表名] set unused column [列名];? ? ? alter table t2 drop unused columns;
5.IOT表、簇表、臨時(shí)表
IOT 索引組織表:這個(gè)表必須有主鍵,會(huì)自動(dòng)地按照主鍵進(jìn)行排序,是個(gè)有序的表。與普通表不同,普通表和表主鍵上的索引都會(huì)需要為它們留出存儲(chǔ)空間,而IOT不存在主鍵的空間開(kāi)銷(xiāo)。索引(主鍵)是存放在一起的;數(shù)據(jù)存儲(chǔ)在索引塊中;所以經(jīng)常通過(guò)主鍵來(lái)訪問(wèn)數(shù)據(jù)的話(huà),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%,當(dāng)一行記錄太大超出了數(shù)據(jù)索引塊的30%,其他列(sname 、sage)就會(huì)放到指定的表空間里users刪除索引表的溢出表,首先要先刪除索引表,然后清空回收站,命令 :?purge recyclebin;
?
簇表:兩個(gè)相互關(guān)聯(lián)的表數(shù)據(jù),同時(shí)放到一個(gè)數(shù)據(jù)塊中。這樣關(guān)聯(lián)查詢(xún)時(shí),就只有掃描1個(gè)數(shù)據(jù)塊就行。
創(chuàng)建簇表步驟如下:簇的數(shù)據(jù)類(lèi)型要和表字段的數(shù)據(jù)類(lèi)型一致。
----1.創(chuàng)建簇----- create cluster cluster1(ckey int); ----2.創(chuàng)建表時(shí)關(guān)聯(lián)簇--------- create table student_cluster(sno int ,sname varchar2(20),sage int )cluster cluster1(sno); ----3.創(chuàng)建另一張表時(shí)關(guān)聯(lián)簇--------- create table record_cluster(sno int ,record int )cluster cluster1(sno); ----4.簇上要建立索引-------create index index1 on cluster cluster1;select * from user_clusters; --查詢(xún)簇的信息select * from user_clu_columns; --查詢(xún)簇的關(guān)聯(lián)信息----------5刪除簇要先把簇表刪除-----------drop table student_cluster;drop table record_cluster;drop cluster cluster1;臨時(shí)表:臨時(shí)表的創(chuàng)建必定在臨時(shí)表空間 TEMP,臨時(shí)表數(shù)據(jù)只能在同一個(gè)session中看到,數(shù)據(jù)不被不同session所共享。每個(gè)session的臨時(shí)表中的數(shù)據(jù)是完全獨(dú)立的;
創(chuàng)建臨時(shí)表語(yǔ)法如下:
create global temporary table student_temp(sno int ,sname varchar2(20),sage int ) --on commit delete rows --(默認(rèn)值);on commit preserve rows;其中 on commit delete rows; 指明了當(dāng)事物提交或回滾時(shí),自動(dòng)把臨時(shí)表數(shù)據(jù)清除; on commit Preserve rows 指明了當(dāng)Session 斷開(kāi)和數(shù)據(jù)庫(kù)連接時(shí)才會(huì)刪除臨時(shí)表中的數(shù)據(jù);
由圖可以知道,兩個(gè)Session 中的臨時(shí)表是完全獨(dú)立的,互不干擾,盡管用戶(hù)都是相同的。指定?on commit preserve rows;的臨時(shí)表 ,其中的數(shù)據(jù)不會(huì)因?yàn)閏ommit而被清空。然而用戶(hù)斷開(kāi)連接時(shí),臨時(shí)表中數(shù)據(jù)才會(huì)刪除。
drop 掉臨時(shí)表的前提是,所有使用這臨時(shí)表的session中表內(nèi)不準(zhǔn)有數(shù)據(jù)。
當(dāng)采用on commit delete rows創(chuàng)建臨時(shí)表時(shí),一提交數(shù)據(jù),表中的數(shù)據(jù)就被清空
查詢(xún)臨時(shí)表信息:
select u.TABLE_NAME as 表名,u.TEMPORARY as 是否是臨時(shí)表,u.DURATION as 是否是事務(wù)型的建表方式from user_tables u where u.TABLE_NAME='STUDENT_TEMP';?
總結(jié)
以上是生活随笔為你收集整理的Oracle 原理:高水位线、PCTFREE、PCTUSED、索引组织表、簇表、临时表的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Oracle 原理: 11g的启动和关闭
- 下一篇: Oracle原理:表分区