Oracle高水位線收縮示例

2021-12-30 00:22:58 字數 2755 閱讀 8292

oracle高水位線收縮示例

一. 背景介紹

我們知道這樣一種情況,在oracle中,假設a表原先有1000w行資料,後來刪除掉了999w行,只剩下1w行資料的時候,全表掃瞄a表的時間沒有什麼變化(刪除前後)。這就是oracle裡面的高水位線引起的。通俗地講,假設我們要裝1000l水,需要1000個桶,後來我倒掉了999個桶裡面的水,但是我沒把桶**。這時,我去找水的時候,仍然要乙個乙個桶地去尋找。下面這個例子就是為了描述這樣一種現象,並介紹怎麼解決(也就是把桶**)

二. 操作步驟

1. 命令列以sys使用者登入

2. 建立測試表

[sql] 

--建立測試表t  

drop table t;  

create table t (  

id number,   

n1 number,   

n2 number,   

pad varchar2(4000)  

) tablespace users ;  

--插入資料10000行  

insert into t  

select rownum as id,  

1+mod(rownum,251) as n1,  

1+mod(rownum,251) as n2,  

dbms_random.string('p',255) as pad  

from dual  

connect by level <= 10000  

order by dbms_random.value;  

3. 收集統計資訊

[sql] 

--收集表t物件統計資訊  

begin  

dbms_stats.gather_table_stats(  

ownname          => user,  

tabname          => 't',  

estimate_percent => 100,  

method_opt       => 'for all columns size skewonly',  

cascade          => true  

);  

end;  

/    

--收集 plan_executetion_statistics(執行計畫 執行時候的資訊)  

alter session set statistics_level = all;  

4. 第一次全表掃瞄獲取的資料行數與邏輯讀數

[sql] 

select /*+ full(t) */ * from t where n2 = 19;  

select *  

from v$sql sqls  

where sqls.sql_text like '%select /*+ full(t) */ * from t where n2 = 19%'  

--引數為上一條sql語句查詢出的sql_id   

select last_output_rows, last_cr_buffer_gets, last_cu_buffer_gets  

from v$sql_plan_statistics stat  

where stat.sql_id = 'chk7agdpy3uqh'  

我電腦上顯示的是last_output_rows: 40,last_cr_buffer_gets: 436,表示返回40行資料,產生了436個邏輯讀(我們這裡假設乙個邏輯讀差不多就是乙個塊,也就是prefetch引數設定得比較大,使得乙個塊一次邏輯讀就讀完了),那麼也就是差不多讀了436個塊。

5. 刪除表中絕大部分資料(大約是9960行)重新查詢行數和邏輯讀數

[sql] 

delete t where n2 <> 19;  

select /*+ full(t) */ * from t where n2 = 19;  

--引數為sql_id  

select last_output_rows, last_cr_buffer_gets, last_cu_buffer_gets  

from v$sql_plan_statistics stat  

where stat.sql_id = 'chk7agdpy3uqh'  

我電腦上顯示的和上一次一樣,說明仍然讀了436個塊。但是已經有絕大部分塊沒有資料了,完全沒必要讀取這些沒資料的塊。

6. 收縮高水位線

[sql] 

alter table t enable row movement;  

alter table t shrink space;  

7. 第三次進行全表掃瞄,重新查詢行數和邏輯讀數

[sql] 

select /*+ full(t) */ * from t where n2 = 19;  

select last_output_rows, last_cr_buffer_gets, last_cu_buffer_gets  

from v$sql_plan_statistics stat  

where stat.sql_id = 'chk7agdpy3uqh'  

我電腦顯示的是 last_output_rows: 40,last_cr_buffer_gets: 4 說明這一次只進行了4次邏輯讀,已經把那些刪除資料的塊全部釋放了。

8. drop測試表

[sql] 

drop table t;  

purge table t;  

Oracle 高水位線收縮示例

一.背景介紹 我們知道這樣一種情況,在oracle中,假設a表原先有1000w行資料,後來刪除掉了999w行,只剩下1w行資料的時候,全表掃瞄a表的時間沒有什麼變化 刪除前後 這就是oracle裡面的高水位線引起的。通俗地講,假設我們要裝1000l水,需要1000個桶,後來我倒掉了999個桶裡面的水...

ORACLE的高水位線

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

oracle 高水位線詳解

一 什麼是水線 high water mark 所有的oracle段 segments,在此,為了理解方便,建議把segment作為表的乙個同義詞 都有乙個在段內容納資料的上限,我們把這個上限稱為 high water mark 或hwm。這個hwm是乙個標記,用來說明已經有多少沒有使用的資料塊分配...