oracle 高水位線詳解

2021-10-09 00:23:20 字數 4791 閱讀 9089

一、什麼是水線(high water mark)?

所有的oracle段(segments,在此,為了理解方便,建議把segment作為表的乙個同義詞) 都有乙個在段內容納資料的上限,我們把這個上限稱為"high water mark"或hwm。這個hwm是乙個標記,用來說明已經有多少沒有使用的資料塊分配給這個segment。hwm通常增長的幅度為一次5個資料塊,原則上hwm只會增大,不會縮小,即使將表中的資料全部刪除,hwm還是為原值,由於這個特點,使hwm很象乙個水庫的歷史最高水位,這也就是hwm的原始含義,當然不能說乙個水庫沒水了,就說該水庫的歷史最高水位為0。但是如果我們在表上使用了truncate命令,則該錶的hwm會被重新置為0。

二、hwm資料庫的操作有如下影響:

a) 全表掃瞄通常要讀出直到hwm標記的所有的屬於該錶資料庫塊,即使該表中沒有任何資料。

三、如何知道乙個表的hwm?

a) 首先對錶進行分析:

analyze table estimate/compute statistics;

b) select blocks, empty_blocks, num_rows

from user_tables

where table_name = ;

說明:blocks 列代表該表中曾經使用過得資料庫塊的數目,即水線。

empty_blocks 代表分配給該錶,但是在水線以上的資料庫塊,即從來沒有使用的資料塊。

讓我們以乙個有28672行的big_emp1表為例進行說明:

sql> select segment_name, segment_type, blocks

from dba_segments

where segment_name=『big_emp1』;

segment_name segment_type blocks

big_emp1 table 1024

1 row selected.

sql> analyze table big_emp1 estimate statistics;

statement processed.

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少1個資料庫塊,這是因為有乙個資料庫塊被保留用作segment header。dba_segments.blocks 表示分配給這個表的所有的資料庫塊的數目。user_tables.blocks表示已經使用過的資料庫塊的數目。

sql> select count (distinct

dbms_rowid.rowid_block_number(rowid)||

dbms_rowid.rowid_relative_fno(rowid)) 「used」

from big_emp1;

used

1 row selected.

sql> delete from big_emp1;

28672 rows processed.

sql> commit;

statement processed.

sql> analyze table big_emp1 estimate statistics;

statement processed.

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.

sql> select count (distinct

dbms_rowid.rowid_block_number(rowid)||

dbms_rowid.rowid_relative_fno(rowid)) 「used」

from big_emp1;

used

0 ----這錶名沒有任何資料庫塊容納資料,即表中無資料

1 row selected.

sql> truncate table big_emp1;

statement processed.

sql> analyze table big_emp1 estimate statistics;

statement processed.

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.

sql> select segment_name,segment_type,blocks

from dba_segments

where segment_name=『big_emp1』;

segment_name segment_type blocks

big_emp1 table 512

1 row selected.

注意:truncate命令**了由delete命令產生的空閒空間,注意該錶分配的空間由原先的1024塊降為512塊。

為了保留由delete命令產生的空閒空間,可以使用truncate table big_emp1 reuse storage.

用此命令後,該錶還會是原先的1024塊。

四、oracle表段中的高水位線hwm

在oracle資料的儲存中,可以把儲存空間想象為乙個水庫,資料想象為水庫中的水。水庫中的水的位置有一條線叫做水位線,在oracle中,這條線被稱為高水位線(high-warter mark, hwm)。在資料庫錶剛建立的時候,由於沒有任何資料,所以這個時候水位線是空的,也就是說hwm為最低值。當插入了資料以後,高水位線就會**,但是這裡也有乙個特性,就是如果你採用delete語句刪除資料的話,資料雖然被刪除了,但是高水位線卻沒有降低,還是你剛才刪除資料以前那麼高的水位。也就是說,這條高水位線在日常的增刪操作中只會**,不會**。

下面我們來談一下oracle中select語句的特性。select語句會對錶中的資料進行一次掃瞄,但是究竟掃瞄多少資料儲存塊呢,這個並不是說資料庫中有多少資料,oracle就掃瞄這麼大的資料塊,而是oracle會掃瞄高水位線以下的資料塊。現在來想象一下,如果剛才是一張剛剛建立的空表,你進行了一次select操作,那麼由於高水位線hwm在最低的0位置上,所以沒有資料塊需要被掃瞄,掃瞄時間會極短。而如果這個時候你首先插入了一千萬條資料,然後再用delete語句刪除這一千萬條資料。由於插入了一千萬條資料,所以這個時候的高水位線就在一千萬條資料這裡。後來刪除這一千萬條資料的時候,由於delete語句不影響高水位線,所以高水位線依然在一千萬條資料這裡。這個時候再一次用select語句進行掃瞄,雖然這個時候表中沒有資料,但是由於掃瞄是按照高水位線來的,所以需要把一千萬條資料的儲存空間都要掃瞄一次,也就是說這次掃瞄所需要的時間和掃瞄一千萬條資料所需要的時間是一樣多的。所以有時候有人總是經常說,怎麼我的表中沒有幾條資料,但是還是這麼慢呢,這個時候其實奧秘就是這裡的高水位線了。

那有沒有辦法讓高水位線下降呢,其實有一種比較簡單的方法,那就是採用truncate語句進行刪除資料。採用truncate語句刪除乙個表的資料的時候,類似於重新建立了表,不僅把資料都刪除了,還把hwm給清空恢復為0。所以如果需要把錶清空,在有可能利用truncate語句來刪除資料的時候就利用truncate語句來刪除表,特別是那種資料量有可能很大的臨時儲存表。

在手動段空間管理(manual segment space management)中,段中只有乙個hwm,但是在oracle9irelease1才新增的自動段空間管理(automatic segment space management)中,又有了乙個低hwm的概念出來。為什麼有了hwm還又有乙個低hwm呢,這個是因為自動段空間管理的特性造成的。在手段段空間管理中,當資料插入以後,如果是插入到新的資料塊中,資料塊就會被自動格式化等待資料訪問。而在自動段空間管理中,資料插入到新的資料塊以後,資料塊並沒有被格式化,而是在第一次在第一次訪問這個資料塊的時候才格式化這個塊。所以我們又需要一條水位線,用來標示已經被格式化的塊。這條水位線就叫做低hwm。一般來說,低hwm肯定是低於等於hwm的。

五、修正oracle表的高水位線

在oracle中,執行對錶的刪除操作不會降低該錶的高水位線。而全表掃瞄將始終讀取乙個段(extent)中所有低於高水位線標記的塊。如果在執行刪除操作後不降低高水位線標記,則將導致查詢語句的效能低下。下面的方法都可以降低高水位線標記。

1.執行表重建指令 alter table table_name move;

2.執行alter table table_name shrink space; 注意,此命令為oracle 10g新增功能,再執行該指令之前必須允許行移動alter table table_name enable row movement;

3.複製要保留的資料到臨時表t,drop原表,然後rename臨時表t為原表

4.emp/imp

5.alter table table_name deallocate unused

6.盡量truncate吧

ORACLE的高水位線

這幾天一直在看乙個問題,乙個統計程式突然統計的資料量不正常了,從頭查到尾,覺得程式和配置都沒有問題,但就是統計出的結果不對,但發現有乙個程式的入庫檔案還存留很多,推斷可能是資料還沒入庫完全,但是什麼導致的呢,以為是那部分檔案太大,入庫太慢,但後來發現還是資料庫的問題,乙個temp表查詢空表都花費很長...

oracle 高水位線問題

查詢高水位線 50295 0 28185 0 select blocks,empty blocks from dba tables where table name todayotherconsumerecords and owner iccardyiwu alter table todayothe...

oracle原理 Oracle高水位線

oracle高水位線的概念 oracle裡面的物件放到儲存級別都稱為segment 段 比如表段,索引段,回滾段等,這些知識segment的邏輯描述。下面就拿錶段為例解釋下。在create table的時候可以指定分配給table的初始空間的大小,一般是都少個extent 區間 extent就是多個...