一. 背景介紹
我們知道這樣一種情況,在oracle中,假設a表原先有1000w行資料,後來刪除掉了999w行,只剩下1w行資料的時候,全表掃瞄a表的時間沒有什麼變化(刪除前後)。這就是oracle裡面的高水位線引起的。通俗地講,假設我們要裝1000l水,需要1000個桶,後來我倒掉了999個桶裡面的水,但是我沒把桶**。這時,我去找水的時候,仍然要乙個乙個桶地去尋找。下面這個例子就是為了描述這樣一種現象,並介紹怎麼解決(也就是把桶**)
二. 操作步驟
1. 命令列以sys使用者登入
2. 建立測試表
--建立測試表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. 收集統計資訊
--收集表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. 第一次全表掃瞄獲取的資料行數與邏輯讀數
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行)重新查詢行數和邏輯讀數
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. 收縮高水位線
alter table t enable row movement;
alter table t shrink space;
7. 第三次進行全表掃瞄,
重新查詢行數和邏輯讀數
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測試表
drop table t;
purge table t;
Oracle高水位線收縮示例
oracle高水位線收縮示例 一.背景介紹 我們知道這樣一種情況,在oracle中,假設a表原先有1000w行資料,後來刪除掉了999w行,只剩下1w行資料的時候,全表掃瞄a表的時間沒有什麼變化 刪除前後 這就是oracle裡面的高水位線引起的。通俗地講,假設我們要裝1000l水,需要1000個桶,...
ORACLE的高水位線
這幾天一直在看乙個問題,乙個統計程式突然統計的資料量不正常了,從頭查到尾,覺得程式和配置都沒有問題,但就是統計出的結果不對,但發現有乙個程式的入庫檔案還存留很多,推斷可能是資料還沒入庫完全,但是什麼導致的呢,以為是那部分檔案太大,入庫太慢,但後來發現還是資料庫的問題,乙個temp表查詢空表都花費很長...
oracle 高水位線詳解
一 什麼是水線 high water mark 所有的oracle段 segments,在此,為了理解方便,建議把segment作為表的乙個同義詞 都有乙個在段內容納資料的上限,我們把這個上限稱為 high water mark 或hwm。這個hwm是乙個標記,用來說明已經有多少沒有使用的資料塊分配...