當前位置:首頁 » 操作系統 » 重建資料庫索引

重建資料庫索引

發布時間: 2023-03-23 04:06:49

sql資料庫重建索引能夠中途退出嗎

可以退出的,索引和數據不是一個概念,不會影響數據的。

㈡ oracle資料庫如何重建索引

用rebuile語句辯遲粗即可啊

Alterindexindex_namerebuild;
Alterindexindex_namerebuildonline;

也可以把索引刪攜鎮除了重新建立旦衡

dropindexindexindex_name;
createindexindexindex_nameontable_name(col_name);

㈢ 在Oracle資料庫中按用戶名重建索引的方法

如果你管理的Oracle資料庫下某些應用項目有大量的修改刪除操作 數據索引是需要周期性爛派的重建的

它不僅可以提高查詢性能 還能增加索引表空間空閑空間大小

在ORACLE里大量刪除記錄後 表和索引里佔用的數據塊空間並沒有釋放

重建索引可以釋放已刪除記錄索引佔用的數據塊空間

轉移數據 重命名的方法可以重新組織表裡的數據

下面是可以按ORACLE用戶名生成重建索引的SQL腳本

SET ECHO OFF; SET FEEDBACK OFF; SET VERIFY OFF; SET PAGESIZE ; SET TERMOUT ON; SET HEADING OFF; ACCEPT username CHAR PROMPT Enter the index username: ; spool /oracle/rebuild_&username sql; SELECT REM + + || chr( ) || REM | INDEX NAME : || owner || || segment_name || lpad( | (length(owner) + length(segment_name)) ) || chr( ) || REM | BYTES : || bytes || lpad ( | (length(bytes)) ) || chr( ) || REM | EXTENTS : || extents || lpad ( | (length(extents)) ) || chr( ) || REM + + || chr( ) || ALTER INDEX || owner || || segment_name || chr( ) || REBUILD || chr( ) || TABLESPACE || tablespace_name || chr( ) || STORAGE ( || chr( ) || INITIAL || initial_extent || chr( ) || NEXT || next_extent || chr( ) || MINEXTENTS || min_extents || chr( ) || MAXEXTENTS || max_extents || chr( ) || PCTINCREASE || pct_increase || chr( ) || ); || chr( ) || chr( ) FROM dba_segments WHERE segment_type = INDEX AND owner= &username ORDER BY owner bytes DESC; spool off;

如果你用的是WINDOWS系統 想改變輸出文件的存放目錄 修改spool後面的路徑成

spool c oraclerebuild_&username sql

如果你只想對大於max_bytes的索引重建索悶檔引 可以修改上面的SQL語句

在AND owner= &username 後面加個限制條件 AND bytes> &max_bytes

如果你想修改索引的存儲參數 在重建索引rebuild_&username sql里改也可以

比如把pctincrease不等於零的值改成是零

生成的rebuild_&username sql文件我們需要來分析一下飢罩賀 它們是否到了需要重建的程度

分析索引 看是否碎片嚴重 SQL>ANALYZE INDEX &index_name VALIDATE STRUCTURE; col name heading Index Name format a col del_lf_rows heading Deleted|Leaf Rows format col lf_rows_used heading Used|Leaf Rows format col ratio heading % Deleted|Leaf Rows format SELECT name del_lf_rows lf_rows del_lf_rows lf_rows_used to_char(del_lf_rows / (lf_rows)* ) ratio FROM index_stats where name = upper( &index_name );

當刪除的比率大於 % 時 肯定是需要索引重建的

經過刪改後的rebuild_&username sql文件我們可以放到ORACLE的定時作業里

比如一個月或者兩個月在非繁忙時間運行

如果遇到ORA 錯誤 表示索引在的表上有鎖信息 不能重建索引

那就忽略這個錯誤 看下次是否成功

對那些特別忙的表要區別對待 不能用這里介紹的方法

lishixin/Article/program/Oracle/201311/19038

㈣ 重建索引是什麼意思

什麼時候需要重建索引

索引在普遍意義上能夠給資料庫帶來帶來提升,但索引的額外開銷也是不容小視的笑凱顫,而索引的孫斗重建也是維護索引的重要工作之一。 經過維護的索引可帶來以下好處:
1、CBO對於索引的使用可能會產生一個較小的成本值,從而在執行計劃中選擇使用索引。
2、使用索引掃描的查詢掃描的物理索引塊會減少,從而提高效率。
3、於需要緩存的索引塊減少了,從而讓出了內存以供其他組件使用。
重建索引的原因主要包括:
1、 刪除的空間沒有重用,導致 索引出現碎片
2、 刪除大量的表數據後,空間沒有重碰敗用,導致 索引"虛高"
3、索引的 clustering_facto 和表不一致
也有人認為當索引樹高度超過4的時候需要進行重建,但是如果表數量級較大,自然就不會有較高的樹,而且重建不會改變索引樹高度,除非是由於大量引起的索引樹「虛高」,重建才會改善性能,當然這又回到了索引碎片的問題上了。

㈤ 如何重建SQL索引 要具體的命令

USE TableName
DECLARE @TableName varchar(255)
DECLARE TableCursor CURSOR FOR
SELECT table_name FROM information_schema.tables
WHERE table_type = 'base table'
OPEN TableCursor
FETCH NEXT FROM TableCursor INTO @TableName
WHILE @@FETCH_STATUS = 0
BEGIN
DBCC DBREINDEX(@TableName,' ',90)
FETCH NEXT FROM TableCursor INTO @TableName
END
CLOSE TableCursor
DEALLOCATE TableCursor

㈥ 資料庫建立索引怎麼利用索引查詢

1.合理使用索引x0dx0a索引是資料庫中重要的數據結構,它的根本目的就是為了提高查詢效率。現在大多數的資料庫產品都採用IBM最先提出的ISAM索引結構。x0dx0a索喚漏引的使用要恰到好處,其使用原則如下:x0dx0a在經常進行連接,但是沒有指定為外鍵的列上建立索引,而不經常連接的欄位則由優化器自動生成索引。x0dx0a在頻繁進行排序或分組(即進行group by或order by操作)的列上建立索引。x0dx0a在條件表達式中經常用到的不同值較多的列上建立檢索,在不同值少的列上不要建立索引。比如在雇員表的「性別」列上只有「男」與「女」兩個不同值,因此就無必要建立索引。如果建立索引不但不會提高查詢效率,反而會嚴重降低更新速度。x0dx0a如果待排序的列有多個,可以在這些列上建立復合索引(compound index)。x0dx0a使用系統工具。如Informix資料庫有一個tbcheck工具,可以在可疑的索引上進行檢查。在一些資料庫伺服器上,索引可能失效或者因為頻繁操作而 使得讀取效率降低,如果一個使用索引的查詢不明不白地慢下來,可以試著用tbcheck工具檢查索引的完整性,必要時進行修復。另外,當資料庫表更新大量 數據後,刪除並重建索引可以提高查詢速度。x0dx0a(1)在下面兩條select語句中:x0dx0aSELECT * FROM table1 WHERE field1<=10000 AND field1>=0; x0dx0aSELECT * FROM table1 WHERE field1>=0 AND field1<=10000;x0dx0a如果數據表中的數據field1都>=0,則第一條select語句要比第二條select語句效率高的多,因為第二條select語句的第一個條件耗費了大量的系統資源。x0dx0a第一個原則:在where子句中應把最具限制性的條件放在最前面。x0dx0a(2)在下面的select語句中:x0dx0aSELECT * FROM tab WHERE a=? AND b=? AND c=?;x0dx0a若有索引index(a,b,c),則where子句中欄位的順序應和索引中欄位順序一致。x0dx0a第二個原則:where子句中欄位的順序應和索引中欄位順序一致。x0dx0a—————————————————————————— x0dx0a以下假設在field1上有唯一索引I1,在field2上有非唯一索引I2。 x0dx0a—————————————喊鏈段————————————— x0dx0a(3) SELECT field3,field4 FROM tb WHERE field1='sdf' 快 x0dx0aSELECT * FROM tb WHERE field1='sdf' 慢[/cci]x0dx0a因為後者在索引掃描後要多一步ROWID表訪問。x0dx0a(4) SELECT field3,field4 FROM tb WHERE field1>='sdf' 快 x0dx0aSELECT field3,field4 FROM tb WHERE field1>'sdf' 慢x0dx0a因為前者可以迅速定位索引。x0dx0a(5) SELECT field3,field4 FROM tb WHERE field2 LIKE 'R%' 快 x0dx0aSELECT field3,field4 FROM tb WHERE field2 LIKE '%R' 慢,x0dx0a因為後者不使用索引。x0dx0a(6) 使用函鄭譽數如: x0dx0aSELECT field3,field4 FROM tb WHERE upper(field2)='RMN'不使用索引。x0dx0a如果一個表有兩萬條記錄,建議不使用函數;如果一個表有五萬條以上記錄,嚴格禁止使用函數!兩萬條記錄以下沒有限制。x0dx0a(7) 空值不在索引中存儲,所以 x0dx0aSELECT field3,field4 FROM tb WHERE field2 IS[NOT] NULL不使用索引。x0dx0a(8) 不等式如 x0dx0aSELECT field3,field4 FROM tb WHERE field2!='TOM'不使用索引。 x0dx0a相似地, x0dx0aSELECT field3,field4 FROM tb WHERE field2 NOT IN('M','P')不使用索引。x0dx0a(9) 多列索引,只有當查詢中索引首列被用於條件時,索引才能被使用。x0dx0a(10) MAX,MIN等函數,使用索引。 x0dx0aSELECT max(field2) FROM tb 所以,如果需要對欄位取max,min,sum等,應該加索引。x0dx0a一次只使用一個聚集函數,如: x0dx0aSELECT 「min」=min(field1), 「max」=max(field1) FROM tb x0dx0a不如:SELECT 「min」=(SELECT min(field1) FROM tb) , 「max」=(SELECT max(field1) FROM tb)x0dx0a(11) 重復值過多的索引不會被查詢優化器使用。而且因為建了索引,修改該欄位值時還要修改索引,所以更新該欄位的操作比沒有索引更慢。x0dx0a(12) 索引值過大(如在一個char(40)的欄位上建索引),會造成大量的I/O開銷(甚至會超過表掃描的I/O開銷)。因此,盡量使用整數索引。 Sp_estspace可以計算表和索引的開銷。x0dx0a(13) 對於多列索引,ORDER BY的順序必須和索引的欄位順序一致。x0dx0a(14) 在sybase中,如果ORDER BY的欄位組成一個簇索引,那麼無須做ORDER BY。記錄的排列順序是與簇索引一致的。x0dx0a(15) 多表聯結(具體查詢方案需要通過測試得到) x0dx0awhere子句中限定條件盡量使用相關聯的欄位,且盡量把相關聯的欄位放在前面。 x0dx0aSELECT a.field1,b.field2 FROM a,b WHERE a.field3=b.field3x0dx0afield3上沒有索引的情況下: x0dx0a對a作全表掃描,結果排序 x0dx0a對b作全表掃描,結果排序 x0dx0a結果合並。 x0dx0a對於很小的表或巨大的表比較合適。x0dx0afield3上有索引 x0dx0a按照表聯結的次序,b為驅動表,a為被驅動表 x0dx0a對b作全表掃描 x0dx0a對a作索引范圍掃描 x0dx0a如果匹配,通過a的rowid訪問x0dx0a(16) 避免一對多的join。如: x0dx0aSELECT tb1.field3,tb1.field4,tb2.field2 FROM tb1,tb2 WHERE tb1.field2=tb2.field2 AND tb1.field2=『BU1032』 AND tb2.field2= 『aaa』 x0dx0a不如: x0dx0adeclare @a varchar(80) x0dx0aSELECT @a=field2 FROM tb2 WHERE field2=『aaa』 x0dx0aSELECT tb1.field3,tb1.field4,@a FROM tb1 WHERE field2= 『aaa』x0dx0a(16) 子查詢 x0dx0a用exists/not exists代替in/not in操作 x0dx0a比較: x0dx0aSELECT a.field1 FROM a WHERE a.field2 IN(SELECT b.field1 FROM b WHERE b.field2=100) x0dx0aSELECT a.field1 FROM a WHERE EXISTS( SELECT 1 FROM b WHERE a.field2=b.field1 AND b.field2=100) x0dx0aSELECT field1 FROM a WHERE field1 NOT IN( SELECT field2 FROM b) x0dx0aSELECT field1 FROM a WHERE NOT EXISTS( SELECT 1 FROM b WHERE b.field2=a.field1)x0dx0a(17) 主、外鍵主要用於數據約束,sybase中創建主鍵時會自動創建索引,外鍵與索引無關,提高性能必須再建索引。x0dx0a(18) char類型的欄位不建索引比int類型的欄位不建索引更糟糕。建索引後性能只稍差一點。x0dx0a(19) 使用count(*)而不要使用count(column_name),避免使用count(DISTINCT column_name)。x0dx0a(20) 等號右邊盡量不要使用欄位名,如: x0dx0aSELECT * FROM tb WHERE field1 = field3x0dx0a(21) 避免使用or條件,因為or不使用索引。x0dx0a2.避免使用order by和group by字句。x0dx0a因為使用這兩個子句會佔用大量的臨時空間(tempspace),如果一定要使用,可用視圖、人工生成臨時表的方法來代替。 x0dx0a如果必須使用,先檢查memory、tempdb的大小。 x0dx0a測試證明,特別要避免一個查詢里既使用join又使用group by,速度會非常慢!x0dx0a3.盡量少用子查詢,特別是相關子查詢。因為這樣會導致效率下降。x0dx0a一個列的標簽同時在主查詢和where子句中的查詢中出現,那麼很可能當主查詢中的列值改變之後,子查詢必須重新查詢一次。查詢嵌套層次越多,效率越低,因此應當盡量避免子查詢。如果子查詢不可避免,那麼要在子查詢中過濾掉盡可能多的行。x0dx0a4.消除對大型錶行數據的順序存取x0dx0a在 嵌套查詢中,對表的順序存取對查詢效率可能產生致命的影響。 x0dx0a比如採用順序存取策略,一個嵌套3層的查詢,如果每層都查詢1000行,那麼這個查詢就要查詢 10億行數據。 x0dx0a避免這種情況的主要方法就是對連接的列進行索引。 x0dx0a例如,兩個表:學生表(學號、姓名、年齡??)和選課表(學號、課程號、成績)。如果兩個 表要做連接,就要在「學號」這個連接欄位上建立索引。 x0dx0a還可以使用並集來避免順序存取。盡管在所有的檢查列上都有索引,但某些形式的where子句強迫優化器使用順序存取。 x0dx0a下面的查詢將強迫對orders表執行順序操作: x0dx0aSELECT * FROM orders WHERE (customer_num=104 AND order_num>1001) OR order_num=1008 x0dx0a雖然在customer_num和order_num上建有索引,但是在上面的語句中優化器還是使用順序存取路徑掃描整個表。因為這個語句要檢索的是分離的行的集合,所以應該改為如下語句: x0dx0aSELECT * FROM orders WHERE customer_num=104 AND order_num>1001 x0dx0aUNION x0dx0aSELECT * FROM orders WHERE order_num=1008 x0dx0a這樣就能利用索引路徑處理查詢。x0dx0a5.避免困難的正規表達式x0dx0aMATCHES和LIKE關鍵字支持通配符匹配,技術上叫正規表達式。但這種匹配特別耗費時間。例如:SELECT * FROM customer WHERE zipcode LIKE 「98_ _ _」 x0dx0a即使在zipcode欄位上建立了索引,在這種情況下也還是採用順序掃描的方式。如果把語句改為SELECT * FROM customer WHERE zipcode >「98000」,在執行查詢時就會利用索引來查詢,顯然會大大提高速度。 x0dx0a另外,還要避免非開始的子串。例如語句:SELECT * FROM customer WHERE zipcode[2,3] >「80」,在where子句中採用了非開始子串,因而這個語句也不會使用索引。x0dx0a6.使用臨時表加速查詢x0dx0a把表的一個子集進行排序並創建臨時表,有時能加速查詢。它有助於避免多重排序操作,而且在其他方面還能簡化優化器的工作。例如: x0dx0aSELECT cust.name,rcvbles.balance,??other COLUMNS x0dx0aFROM cust,rcvbles x0dx0aWHERE cust.customer_id = rcvlbes.customer_id x0dx0aAND rcvblls.balance>0 x0dx0aAND cust.postcode>「98000」 x0dx0aORDER BY cust.name x0dx0a如果這個查詢要被執行多次而不止一次,可以把所有未付款的客戶找出來放在一個臨時文件中,並按客戶的名字進行排序: x0dx0aSELECT cust.name,rcvbles.balance,??other COLUMNS x0dx0aFROM cust,rcvbles x0dx0aWHERE cust.customer_id = rcvlbes.customer_id x0dx0aAND rcvblls.balance>;0 x0dx0aORDER BY cust.name x0dx0aINTO TEMP cust_with_balance x0dx0a然後以下面的方式在臨時表中查詢: x0dx0aSELECT * FROM cust_with_balance x0dx0aWHERE postcode>「98000」 x0dx0a臨時表中的行要比主表中的行少,而且物理順序就是所要求的順序,減少了磁碟I/O,所以查詢工作量可以得到大幅減少。 x0dx0a注意:臨時表創建後不會反映主表的修改。在主表中數據頻繁修改的情況下,注意不要丟失數據。x0dx0a7.用排序來取代非順序存取x0dx0a非順序磁碟存取是最慢的操作,表現在磁碟存取臂的來回移動。SQL語句隱藏了這一情況,使得我們在寫應用程序時很容易寫出要求存取大量非順序頁的查詢。

㈦ 如何重建資料庫所有索引

當對數據的更改影響到索引時,索悶含引孫罩雀中的信息可能會在資料庫中分散開來。重建索引可以重新組織索引數據(對於聚集索引還包括表數據)的存儲,清除碎片。這可通過減少獲得請求數據則早所需的頁讀取數來提高磁碟性能。
在Microsoft

㈧ 在PL-SQL中如何給oracle資料庫重建索引

重建索引有多種方式,如drop and re-create、rebuild、rebuild online等。下面簡單比較空襲這幾種方式異同以及優缺點:
首先建立測試表及數據:
SQL> CREATE TABLE TEST AS SELECT CITYCODE C1 FROM CITIZENINFO2;
Table created
SQL> ALTER TABLE TEST MODIFY C1 NOT NULL;
Table altered
SQL> SELECT COUNT(1) FROM TEST;
COUNT(1)
----------
16000000
一、drop and re-create和rebuild
首先看看正常建立索引時,對表的加鎖情況。
suk@ORACLE9I> @show_sid
SID
----------
14
suk@ORACLE9I> CREATE INDEX IDX_TEST_C1 ON TEST(C1);
索引已創建。
SQL> SELECT OBJECT_NAME,LMODE FROM V$LOCK L,DBA_OBJECTS O WHERE O.OBJECT_ID=L.ID1 AND L.TYPE='TM' AND SID=14;
OBJECT_NAME LMODE
------------------------------ ----------
OBJ$ 3
TEST 4
可見,普通情況下建立索引時,oracle會對基表加share鎖,由於share鎖和 row-X是不兼容的,也就是說,在建立索引期間,無法對基表進行DML操作。
對於刪除重建索引的方法就不介紹了,它與上面的描述是一樣的,下面我們看看用rebuild的方式建立索引有什麼特別。
suk@ORACLE9I> ALTER INDEX IDX_TEST_C1 REBUILD;
索引已更改。
另開一個會話,查詢此時test的加鎖情況:
SQL> SELECT OBJECT_NAME,LMODE FROM V$LOCK L,DBA_OBJECTS O WHERE O.OBJECT_ID=L.ID1 AND L.TYPE='TM' AND SID=14;
OBJECT_NAME LMODE
------------------------------ ----------
TEST 4
可見,rebuild的方式對基表的加鎖方式與CREATE時是一樣的。
另開一個會話,在索引正在rebuild時,執行如下SQL:
suk@ORACLE9I> SET AUTOTRACE TRACE
suk@ORACLE9I> SELECT /*+ INDEX(TEST) */ COUNT(1) FROM TEST WHERE ROWNUM<10;
執行計劃
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE (Cost=26 Card=1)
1 0 SORT (AGGREGATE)
2 1 COUNT (STOPKEY)
3 2 INDEX (FULL SCAN) OF 'IDX_TEST_C1' (NON-UNIQUE) (Cost=
26 Card=1986621)
可以看到索引在重建時,查詢仍然可以使用舊索引。實際上,oracle在rebuild時,在創建新索引過程中,並不會刪除舊索引,直到新索引rebuild成功。
從這點可以知道rebuild比刪除重建的一個好處是不肆和會影響原有的SQL查詢,但也正由於此,用rebuild方式建立索引需要相應表空間的空閑空間是刪除重建方式的2倍。
重建索引有多種方式,如drop and re-create、rebuild、rebuild online等。下面簡單比較這幾種方式異同以及裂虧盯優缺點:
相關文章:
oracle重建索引(一)
二、rebuild 和rebuild online
首先我們跟蹤一下rebuild online的過程。
另開一個會話查看鎖的信息:
SQL> SELECT OBJECT_NAME,LMODE FROM V$LOCK L,DBA_OBJECTS O WHERE O.OBJECT_ID=L.ID1 AND L.TYPE='TM' AND SID=14;
OBJECT_NAME LMODE
------------------------------ ----------
SYS_JOURNAL_10499 4
TEST 2
SQL> INSERT INTO TEST VALUES(11);
1 row inserted
SQL> COMMIT;
Commit complete
可以看到,在rebuild online期間,oracle對基表加的是RS所,此時我們可以對基表進行DML操作。但奇怪的話在相同的session中有一個SYS_JOURNAL_10499表被加SHARE鎖,這個表是干什麼用的呢?
我們看看trace文件,有這樣的信息:
create table "SUK"."SYS_JOURNAL_10499" (C0 NUMBER(6,0), opcode char(1),
partno number, rid rowid, primary key( C0 , rid )) organization index
TABLESPACE "TEST"
CREATE UNIQUE INDEX "SUK"."SYS_IOT_TOP_10605" on
"SUK"."SYS_JOURNAL_10499"("C0","RID") INDEX ONLY TOPLEVEL TABLESPACE "TEST"
NOPARALLEL
drop table "SUK"."SYS_JOURNAL_10499"
我們在查查10499是什麼東西:
SQL> SELECT OBJECT_NAME,OBJECT_TYPE FROM DBA_OBJECTS WHERE OBJECT_ID=10499;
OBJECT_NAME OBJECT_TYPE
------------------------------ ------------------
IDX_TEST_C1 INDEX
從這些信息可以推測:表SYS_JOURNAL_10499就是實現在重建索引時不阻塞DML操作而設計的,它存儲的是在索引重建期間發生在基表的數據變化。可以推測,CREATE INDEX .... ONLINE應該也有一張類似的表。
實際上,oracle之所以在創建索引時鎖表阻止DML操作就是為了防止不能索引新變化的數據,在online方式重建時,有了臨時表SYS_JOURNAL_XXXX,oracle就可以放心大膽地讓用戶操作了,因為所有重建索引期間的數據變化信息都會保留在SYS_JOURNAL_XXX表中,當索引重建完後再加上SYS_JOURNAL_XXX記錄的數據,就不會漏索引數據了。(XXX是被重建的索引對應的OBJECT_ID)
導讀:
重建索引有多種方式,如drop and re-create、rebuild、rebuild online等。下面簡單比較這幾種方式異同以及優缺點:
相關文章:
oracle重建索引(一)
oracle重建索引(二)
三、rebuild和rebuild online的數據源
網上一直有這樣一個說法:重建索引是以原索引作為數據源的。那麼,這種說法是否准確呢?我們做實驗來驗證一下:
suk@ORACLE9I> COL SEGMENT_NAME FORMAT A30
--首先看看錶和索引的大小
suk@ORACLE9I> SELECT SEGMENT_NAME,BYTES FROM USER_SEGMENTS WHERE SEGMENT_NAME IN ('TEST','IDX_TEST_C1');
SEGMENT_NAME BYTES
------------------------------ ----------
TEST 201326592
IDX_TEST_C1 293601280
suk@ORACLE9I> EXPLAIN PLAN FOR ALTER INDEX IDX_TEST_C1 REBUILD;
已解釋。
suk@ORACLE9I> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
-----------------------------------------------------------------------
| 0 | ALTER INDEX STATEMENT | | | | |
| 1 | INDEX BUILD NON UNIQUE| IDX_TEST_C1 | | | |
| 2 | SORT CREATE INDEX | | | | |
| 3 | TABLE ACCESS FULL | TEST | | | |
-----------------------------------------------------------------------
Note: rule based optimization
已選擇11行。
--從執行計劃可以看出,當索引比表大時,rebuild索引用的數據源是基表。
suk@ORACLE9I> EXPLAIN PLAN FOR ALTER INDEX IDX_TEST_C1 REBUILD ONLINE;
已解釋。
suk@ORACLE9I> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
-----------------------------------------------------------------------
| 0 | ALTER INDEX STATEMENT | | | | |
| 1 | INDEX BUILD NON UNIQUE| IDX_TEST_C1 | | | |
| 2 | SORT CREATE INDEX | | | | |
| 3 | TABLE ACCESS FULL | TEST | | | |
-----------------------------------------------------------------------
Note: rule based optimization
已選擇11行。
--從執行計劃可以看出,當索引比表大時,rebuild online索引用的數據源是基表。
--我們為TEST添加一列,使得表比索引大
suk@ORACLE9I> ALTER TABLE TEST ADD(C2 CHAR(30) DEFAULT '1');
表已更改。
suk@ORACLE9I> SELECT SEGMENT_NAME,BYTES FROM USER_SEGMENTS WHERE SEGMENT_NAME IN ('TEST','IDX_TEST_C
1');
SEGMENT_NAME BYTES
------------------------------ ----------
TEST 1476395008
IDX_TEST_C1 293601280
suk@ORACLE9I> EXPLAIN PLAN FOR ALTER INDEX IDX_TEST_C1 REBUILD;
已解釋。
suk@ORACLE9I> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
-----------------------------------------------------------------------
| 0 | ALTER INDEX STATEMENT | | | | |
| 1 | INDEX BUILD NON UNIQUE| IDX_TEST_C1 | | | |
| 2 | SORT CREATE INDEX | | | | |
| 3 | INDEX FAST FULL SCAN| IDX_TEST_C1 | | | |
-----------------------------------------------------------------------
Note: rule based optimization
已選擇11行。
--從執行計劃可以看出,當表比索引大時,執行計劃已經改變,rebuild索引是以索引作為數據源的。
suk@ORACLE9I> EXPLAIN PLAN FOR ALTER INDEX IDX_TEST_C1 REBUILD ONLINE;
已解釋。
suk@ORACLE9I> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
-----------------------------------------------------------------------
| 0 | ALTER INDEX STATEMENT | | | | |
| 1 | INDEX BUILD NON UNIQUE| IDX_TEST_C1 | | | |
| 2 | SORT CREATE INDEX | | | | |
| 3 | TABLE ACCESS FULL | TEST | | | |
-----------------------------------------------------------------------
Note: rule based optimization
已選擇11行。
--從執行計劃可以看出,當表比索引大時,rebuild online仍然以基表作為數據源。
rebuild模式下,因為表數據不會產生變化,oracle主要考慮性能問題,把更快掃描完成的段作為數據源。在上面的例子中,我們並沒有對表進行分析,故oracle應該根據數據段的大小來決定那個作為數據源的。一般索引欄位比較多,或者對索引欄位的DML操作較多,可能會導致索引比表大,這時oracle就會使用基表作為新索引的數據源進行rebuild了。
而在rebuild online模式下,因為允許DML操作,而表數據變化的同時索引也會跟著變化,為了索引與基表數據的一致性,比如採用基表數據作為數據源,而不能用原索引數據作為數據源。
我們用反證法證明不能用原索引作為新索引的數據源。
例如:
T1發出rebuild online命令
T2刪除某條數據,刪數據的同時,oracle會自動維護了舊索引
T3掃描經過T2數據所在索引節點
T4插入一條記錄,新記錄對應的索引節點剛好重用了T2刪除的數據對應的索引節點空間
如果是這樣的話,新建的索引將不包含T4插入的記錄的信息。所以,rebuild online情況下新索引的數據源不能是原索引。
rebuild online情況下,如果非用原索引作為新索引的數據源的話,用中間表記錄索引變化的方法應該是可以實現的,但由於數據變化會同時引起索引變化的特定決定了這種方法將異常復雜及效率底下,所以oracle不考慮舊索引作為新索引的數據源是有道理的。
結論:
1、rebuild會阻塞對基表的DML操作,但不會影響rebuild期間查詢對原有索引的使用。
2、rebuild的數據源可能是基表,也可能是原索引。取決於基表和原索引的大小,那個小,rebuild時就會用那個作為數據源。這也說明了網上盛傳的rebuild以原索引作為資料庫的說法是不完全正確的。
3、rebuild online運行用戶在索引重建期間執行DML操作。
4、rebuild online的數據源是基表

㈨ 重建索引是什麼意思

什麼時候需要重建索引
索引在普遍意義上能夠給資料庫帶來帶來提升,但索引的額外開銷也是不容小視的,而索引的重建也是維護索引的重要工作之一。
經過維護的索引可帶來以下好處:
1、CBO對於索引的使用可能會產生一個較小的成本值,從而裂神在執行計劃中選擇使用索引。
2、使用索引掃描的查詢掃描的物理索引塊會減少,從而提高效率。
3、於需要緩存的索引塊減少培譽了,從而讓出了內存以供其他組件使用。
重建索引的原因主要包括:
1、
刪除的空間沒有重用,導致
索引出現碎片
2、
刪除大量的表數據後,空間沒有重用,導致
索引"虛高"
3、索引的
clustering_facto
和表不一致配源段
也有人認為當索引樹高度超過4的時候需要進行重建,但是如果表數量級較大,自然就不會有較高的樹,而且重建不會改變索引樹高度,除非是由於大量引起的索引樹「虛高」,重建才會改善性能,當然這又回到了索引碎片的問題上了。

熱點內容
介紹高德地圖如何查看電腦配置 發布:2024-04-20 23:03:37 瀏覽:994
演算法加運維 發布:2024-04-20 23:03:30 瀏覽:390
android匹配 發布:2024-04-20 22:58:33 瀏覽:168
string的長度java 發布:2024-04-20 22:46:20 瀏覽:136
網易我的世界監獄風雲的伺服器 發布:2024-04-20 22:35:41 瀏覽:186
linux服務自動重啟 發布:2024-04-20 22:34:54 瀏覽:962
編譯器最後的結果 發布:2024-04-20 22:30:38 瀏覽:821
安裝linuxoracle11g 發布:2024-04-20 22:29:02 瀏覽:533
android設置權重 發布:2024-04-20 22:20:08 瀏覽:725
什麼手機安卓系統80 發布:2024-04-20 21:37:29 瀏覽:380