經常會遇到乙個表,其中只有幾條資料,結果查詢一下表記錄總數,發現特別的慢。這通常是由於oracle高水位線的問題引起的,見[1]。這樣的表在實際應用中也不枚勝舉,比如簡訊傳送表,一次大批量傳送了500萬條簡訊,發完後表的記錄全被刪除(是delete,而不是truncate掉),之後查詢該錶會非常慢。原因在於delete操作並不會**表被刪除的空間,導致全表掃瞄時仍舊需要掃瞄那些記錄已經全部被刪除的塊,導致速度和delete操作前沒有變化。如果呼叫alter table *** shrink space收縮一下表,問題即解決。
本文即建了乙個測試表(表有1個varchar2型的字段,長度為1024個byte)模擬了這個過程。先插入50萬條記錄,故表占用總空間約為500m(=500,000*1024)。之後進行delete操作,只保留其中一條記錄。之後查詢速度和delete前一樣,收縮一下表之後,幾個毫秒即即可返回結果。
-- 建立測試表
create table lcm_test(c1 int, c2 varchar2(1024));
--truncate table lcm_test;
-- 統計表記錄行數(沒有任何索引,採用全表掃瞄)
select count(*) from lcm_test;
-- 收集統計資訊
analyze table lcm_test estimate statistics;
--察看表統計資訊
select *
--select count(*)
from all_tables
where table_name = 'lcm_test';
-- 插入測試資料
declare
begin
for i in 1 .. 500000 loop
insert into lcm_test(c1, c2)
values (i, lpad('a', 1024, 'a'));
if mod(i, 1000) = 0 then
commit;
end if;
end loop;
commit;
end;
-- 只保留一條記錄
delete from lcm_test where c1 > 1;
commit;
-- 統計表記錄行數(沒有任何索引,採用全表掃瞄)
-- 由於delete並不會**空間,故仍舊需要掃瞄記錄已經全被刪除的塊
-- 此時若收集lcm_test表的統計資料,與delete操作之前並沒有變化
select count(*) from lcm_test;
-- **表被刪除空間
alter table lcm_test enable row movement;
alter table lcm_test shrink space;
-- 收縮之後,lcm_test只剩下乙個塊,全表掃瞄瞬間完成
[1] oracle高水位線問題 http://blog.chinaunix.net/u2/60332/showart_495441.html
ORACLE的高水位線
這幾天一直在看乙個問題,乙個統計程式突然統計的資料量不正常了,從頭查到尾,覺得程式和配置都沒有問題,但就是統計出的結果不對,但發現有乙個程式的入庫檔案還存留很多,推斷可能是資料還沒入庫完全,但是什麼導致的呢,以為是那部分檔案太大,入庫太慢,但後來發現還是資料庫的問題,乙個temp表查詢空表都花費很長...
oracle 高水位線詳解
一 什麼是水線 high water mark 所有的oracle段 segments,在此,為了理解方便,建議把segment作為表的乙個同義詞 都有乙個在段內容納資料的上限,我們把這個上限稱為 high water mark 或hwm。這個hwm是乙個標記,用來說明已經有多少沒有使用的資料塊分配...
oracle 高水位線問題
查詢高水位線 50295 0 28185 0 select blocks,empty blocks from dba tables where table name todayotherconsumerecords and owner iccardyiwu alter table todayothe...