重建績效
大多數Oracle專家對此表示懷疑經常重建索引。例如,快速瀏覽演示文稿Rebuilding the Truth會告訴你,索引不會以許多人認爲他們所做的天真方式行事。
該演示文稿中的一個相關要點是「完全刪除的塊被回收並且通常不成問題」。如果你的價值完全改變,那麼你的指數不應該變得無限大。雖然您的索引以非典型方式使用,但這種行爲可能是一件好事。
下面是一個簡單的例子。創建100萬行並將其索引爲100。
--Create table, constraints, and index.
CREATE TABLE T
(
id_t integer primary key,
text varchar2(100),
a integer check (a is null or a = 1)
);
CREATE INDEX IDX_T$A ON T(a);
--Insert 1M rows, with 100 "1"s.
insert into t
select level, level, case when mod(level, 10000) = 0 then 1 else null end
from dual connect by level <= 1000000;
commit;
--Initial sizes:
select segment_name, bytes/1024/1024 MB
from dba_segments
where segment_name in ('T', 'IDX_T$A');
SEGMENT_NAME MB
T 19
IDX_T$A 0.0625
現在完全洗牌索引行大約1000次。
--Move the 1s around 1000 times. Takes about 6 minutes.
begin
for i in 9000 .. 10000 loop
update t
set a = case when mod(id_t, i) = 0 then 1 else null end
--Don't update if the vlaue is the same
where nvl(a,-1) <> nvl(case when mod(id_t,i) = 0 then 1 else null end,-1);
commit;
end loop;
end;
/
索引段大小仍然相同。
--The the index size is the same.
select segment_name, bytes/1024/1024 MB
from dba_segments
where segment_name in ('T', 'IDX_T$A');
SEGMENT_NAME MB
T 19
IDX_T$A 0.0625
重建統計
這是很好的擔心對象,其數據變化如此顯着的統計信息。但是,同樣,儘管你的系統不常見,但在默認的Oracle行爲下它可能正常工作。雖然索引的行可能完全改變,但相關的統計數據可能保持不變。如果總是有100行索引,則行數,塊數和獨特性將保持不變。
如果100行從完全隨機變爲彼此非常接近,也許聚類因子會發生顯着變化。但即使這可能並不重要。如果有數百萬行,但只有100個索引,那麼優化程序的決定可能是相同的,無論聚類因子如何。讀取1個塊(令人敬畏的聚類因子)或讀取100個塊(最壞情況聚類因子)仍然比完成數百萬行的全表掃描要好得多。
但統計很複雜,我肯定是過分簡化了事情。如果您需要以特定方式保留統計信息,則可能需要鎖定它們。不幸的是,你不能只鎖定一個索引,但你可以鎖定表和它的依賴索引。
begin
dbms_stats.lock_table_stats(ownname => user, tabname => 'T');
end;
/
重建反正
如果重建仍然是必要的,@Robe Eleckers想法重新嘗試應該工作。雖然不是例外,但設置DDL_LOCK_TIMEOUT會更容易。
alter session set ddl_lock_timeout = 500;
該會話仍然需要在表格上獲得排他鎖定,但這樣會更容易找到合適的機會窗口。
你可以用重試機制來處理它。捕獲資源繁忙異常並再次嘗試,直到成功。 –
快速變化對您的索引有什麼影響,導致需要進行這些頻繁重建? –
統計數據過期非常快。重新編譯會統計數據並使索引更小(讀取查詢會變得更快)。 – ZZa