什么是高水位線(High Water Mark
----------------------------
oracle的邏輯存儲(chǔ)結(jié)構(gòu):表空間——>段——>區(qū)——>塊
塊:是粒度最小的存儲(chǔ)單位,現(xiàn)在標(biāo)準(zhǔn)的塊大小是8K,ORACLE每一次I/O操作也是按塊來(lái)操作的,也就是說(shuō)當(dāng)ORACLE從數(shù)據(jù)文件讀數(shù)據(jù)時(shí),是讀取多少個(gè)塊,而不是多少行.
區(qū):由一系列相鄰的塊而組成,這也是ORACLE空間分配的基本單位,舉個(gè)例子來(lái)說(shuō),當(dāng)我們創(chuàng)建一個(gè)表A時(shí),首先ORACLE會(huì)分配一區(qū)的空間給這個(gè)表,隨著不斷的INSERT數(shù)據(jù)到A,原來(lái)的這個(gè)區(qū)容不下插入的數(shù)據(jù)時(shí),ORACLE是以區(qū)為單位進(jìn)行擴(kuò)展的,也就是說(shuō)再分配多少個(gè)區(qū)給A,而不是多少個(gè)塊.
段:是由一系列的區(qū)所組成,一般來(lái)說(shuō),當(dāng)創(chuàng)建一個(gè)對(duì)象時(shí)(表,索引),就會(huì)分配一個(gè)段給這個(gè)對(duì)象.所以從某種意義上來(lái)說(shuō),段就是某種特定的數(shù)據(jù).如CREATE
TABLE PM_USER,這個(gè)段就是數(shù)據(jù)段,而CREATE INDEX ON
PM_USER(NAME),ORACLE同樣會(huì)分配一個(gè)段給這個(gè)索引,但這是一個(gè)索引段了.查詢段的信息可以通過(guò)數(shù)據(jù)字典: SELECT
* FROM USER_SEGMENTS來(lái)獲得,
表空間:包含段,區(qū)及塊.表空間的數(shù)據(jù)物理上儲(chǔ)存在其所在的數(shù)據(jù)文件中.一個(gè)數(shù)據(jù)庫(kù)至少要有一個(gè)表空間.
所有的oracle段都有一個(gè)在段內(nèi)容納數(shù)據(jù)的上限,我們把這個(gè)上限稱為"high water
mark"或HWM。這個(gè)HWM是一個(gè)標(biāo)記,用來(lái)說(shuō)明已經(jīng)有多少空閑數(shù)據(jù)塊分配給這個(gè)segment。
HWM通常增長(zhǎng)的幅度為一次5個(gè)數(shù)據(jù)塊,,原則上HWM只會(huì)增大,,不會(huì)縮小,,即使將表中的數(shù)據(jù)全部刪除,,HWM還是為原值,,由于這個(gè)特點(diǎn),HWM很象一個(gè)水庫(kù)的歷史最高水位,,這也就是HWM的原始含義,,當(dāng)然不能說(shuō)一個(gè)水庫(kù)沒水了,就說(shuō)該水庫(kù)的歷史最高水位為0,。但是如果我們?cè)诒砩鲜褂昧藅runcate命令,,則該表的HWM會(huì)被重新置為0。
HWM數(shù)據(jù)庫(kù)的操作有如下影響: a) 全表掃描通常要讀出直到HWM標(biāo)記的所有的屬于該表數(shù)據(jù)庫(kù)塊,,即使該表中沒有任何數(shù)據(jù),。 b) 即使HWM以下有空閑的數(shù)據(jù)庫(kù)塊,鍵入在插入數(shù)據(jù)時(shí)使用了append關(guān)鍵字,,則在插入時(shí)使用HWM以上的數(shù)據(jù)塊,,此時(shí)HWM會(huì)自動(dòng)增大。 如何知道一個(gè)表的HWM,? a) 首先對(duì)表進(jìn)行分析: ANALYZE TABLE <tablename> ESTIMATE/COMPUTE STATISTICS; b) SELECT blocks, empty_blocks, num_rows FROM user_tables WHERE table_name = <tablename>; BLOCKS 列代表該表中曾經(jīng)使用過(guò)得數(shù)據(jù)庫(kù)塊的數(shù)目,,即高水位線 EMPTY_BLOCKS 代表分配給該表,但是在水線以上的數(shù)據(jù)庫(kù)塊,,即從來(lái)沒有使用的數(shù)據(jù)塊,。 讓我們以一個(gè)有28672行的BIG_EMP1表為例進(jìn)行說(shuō)明: 1) SQL> SELECT segment_name,segment_type,blocks FROM dba_segments WHERE segment_name='BIG_EMP1'; SEGMENT_NAME SEGMENT_TYPE BLOCKS EXTENTS ----------------------------- ----------------- ---------- ------- BIG_EMP1 TABLE 1024 2 1 row selected. 2) SQL> ANALYZE TABLE big_emp1 ESTIMATE STATISTICS; Statement processed. 3) SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='BIG_EMP1'; TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS ------------------------------ ---------- ---------- ------------ BIG_EMP1 28672 700 323 1 row selected. 注意: BLOCKS + EMPTY_BLOCKS (700+323=1023)比DBA_SEGMENTS.BLOCKS少個(gè)數(shù)據(jù)庫(kù)塊,這是因?yàn)橛幸粋€(gè)數(shù)據(jù)庫(kù)塊被保留用作segment header,。DBA_SEGMENTS.BLOCKS 表示分配給這個(gè)表的所有的數(shù)據(jù)庫(kù)塊的數(shù)目,。USER_TABLES.BLOCKS表示已經(jīng)使用過(guò)的數(shù)據(jù)庫(kù)塊的數(shù)目。 4) SQL> SELECT COUNT (DISTINCT DBMS_ROWID.ROWID_BLOCK_NUMBER(rowid)|| DBMS_ROWID.ROWID_RELATIVE_FNO(rowid)) "Used" FROM big_emp1; Used ---------- 700 1 row selected. 5) SQL> DELETE from big_emp1; 28672 rows processed. 6) SQL> commit; Statement processed. 7) SQL> ANALYZE TABLE big_emp1 ESTIMATE STATISTICS; Statement processed. 8) SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='BIG_EMP1'; TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS ------------------------------ ---------- ---------- ------------ BIG_EMP1 0 700 323 1 row selected. 9) SQL> SELECT COUNT (DISTINCT DBMS_ROWID.ROWID_BLOCK_NUMBER(rowid)|| DBMS_ROWID.ROWID_RELATIVE_FNO(rowid)) "Used" FROM big_emp1; Used ---------- 0 -- 這表名沒有任何數(shù)據(jù)庫(kù)塊容納數(shù)據(jù),,即表中無(wú)數(shù)據(jù) 1 row selected. 10) SQL> TRUNCATE TABLE big_emp1; Statement processed. 11) SQL> ANALYZE TABLE big_emp1 ESTIMATE STATISTICS; Statement processed. 12) SQL> SELECT table_name,num_rows,blocks,empty_blocks 2> FROM user_tables 3> WHERE table_name='BIG_EMP1'; TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS ------------------------------ ---------- ---------- ------------ BIG_EMP1 0 0 511 1 row selected. 13) SQL> SELECT segment_name,segment_type,blocks FROM dba_segments WHERE segment_name='BIG_EMP1'; SEGMENT_NAME SEGMENT_TYPE BLOCKS EXTENTS ----------------------------- ----------------- ---------- ------- BIG_EMP1 TABLE 512 1 1 row selected. 注意: TRUNCATE命令回收了由delete命令產(chǎn)生的空閑空間,,注意該表分配的空間由原先的1024塊降為512塊。 為了保留由delete命令產(chǎn)生的空閑空間,,可以使用 TRUNCATE TABLE big_emp1 REUSE STORAGE 用此命令后,,該表還會(huì)是原先的1024塊。 補(bǔ)充:
在手動(dòng)段空間管理(Manual Segment Space
Management)中,,段中只有一個(gè)HWM,,但是在Oracle9iRelease1才添加的自動(dòng)段空間管理(Automatic Segment Space
Management)中,又有了一個(gè)低HWM的概念出來(lái),。為什么有了HWM還又有一個(gè)低HWM呢,,這個(gè)是因?yàn)樽詣?dòng)段空間管理的特性造成的。在手段段空間管理中,,當(dāng)數(shù)據(jù)插入以后,,如果是插入到新的數(shù)據(jù)塊中,,數(shù)據(jù)塊就會(huì)被自動(dòng)格式化等待數(shù)據(jù)訪問(wèn)。而在自動(dòng)段空間管理中,,數(shù)據(jù)插入到新的數(shù)據(jù)塊以后,,數(shù)據(jù)塊并沒有被格式化,而是在第一次在第一次訪問(wèn)這個(gè)數(shù)據(jù)塊的時(shí)候才格式化這個(gè)塊,。所以我們又需要一條水位線,,用來(lái)標(biāo)示已經(jīng)被格式化的塊。這條水位線就叫做低HWM,。一般來(lái)說(shuō),,低HWM肯定是低于等于HWM的。 1.執(zhí)行表重建指令 alter table table_name move; ************************************************************ |
|