oracle全文索引之同步和優化索引做了什麼
我們知道,在資料被修改後,不能被查詢到了,直到索引被同步。那麼同步索引做了那些工作呢?
suk@oracle9i> insert into t_domain values(3,'this is beijing');
已建立 1 行。
suk@oracle9i> update t_domain set doc='this is beijing' where id=3;
已更新 1 行。
suk@oracle9i> delete from t_domain where id=5;
已刪除 1 行。
suk@oracle9i> commit;
提交完成。
suk@oracle9i> @begin_tracesuk@oracle9i> exec ctx_ddl.sync_index('IDX_DOMAIN');suk@oracle9i> @end_trace
摘取trace中主要的sql如下:
--發出索引同步命令
BEGIN ctx_ddl.sync_index('IDX_DOMAIN'); END;
--刪除DR$WAITING中與DR$PENGING重複的資訊
DELETE FROM DR$WAITING
WHERE
WTG_CID = :b1 AND WTG_PID = :b2 AND EXISTS (SELECT 1 FROM DR$PENDING
WHERE DR$PENDING.PND_CID = DR$WAITING.WTG_CID AND DR$PENDING.PND_PID =
DR$WAITING.WTG_PID AND DR$PENDING.PND_ROWID = DR$WAITING.WTG_ROWID )
這一步很重要,我們在《oracle全文索引之幾個關鍵表》中介紹了DR$WAITING的使用原理,為了避免重複同步同一條記錄的索引,提高效率,必須刪除掉DR$WAITING中多餘的資訊。
在刪除DR$WAITING的多餘資訊後,oracle會把DR$WAITING的記錄與DR$PENGDING的記錄聯合,得到最終需要同步的記錄的集合。
(因為這個實驗中DR$WAITING表中的資料完全是DR$PENDING的子集,所以,trace沒有反應合併這一步)
--通過一定的分詞演算法,把產生的資訊插入到$I表中
insert into "SUK"."DR$IDX_DOMAIN$I"
values
(:token, :ttype, :first, :last, :count, :data)
--插入記錄到$K表中
insert into "SUK"."DR$IDX_DOMAIN$K" (textkey, docid)
values
(:akeys, :adocs)
--更新$R表
select data
from
"SUK"."DR$IDX_DOMAIN$R" where row_no = :row_no for update
在trace中並沒有更新$R的直接資訊,但我猜測在同步索引時會更新$R表
--刪除DR$PENGING的資訊
delete from dr$pending
where
pnd_cid = :cid and pnd_pid = :pid and pnd_rowid = :rid
實際上,我猜測,如果刪除DR$WAITING中與DR$PENGING重複的資訊後,DR$WAITING還有記錄的話,這一步還會刪除DR$WAITIING的記錄的。
--最後提交
commit
二、優化索引做了什麼
優化索引可以有很多方式,不同的優化方式得到的結果會不一樣,但原理應該是差不多的。我們以FULL優化為例說明。
緊接著上面的例子,我們發出命令:
suk@oracle9i> @begin_tracesuk@oracle9i> exec ctx_ddl.optimize_index('idx_domain','FULL');suk@oracle9i> @end_trace
從trace檔案中摘取主要的sql:
--發出命令
BEGIN ctx_ddl.optimize_index('idx_domain','FULL'); END;
--將DR$INDEX的部分欄位設定為空
UPDATE DR$INDEX SET IDX_OPT_TOKEN= NULL ,IDX_OPT_TYPE= NULL ,IDX_OPT_COUNT=
NULL
WHERE
IDX_ID = :b1
其中:
IDX_OPT_TOKEN:當次優化的起始關鍵字
IDX_OPT_COUNT:當次優化的doc數量
--將$N表的doc設定為需要被優化狀態
update "SUK"."DR$IDX_DOMAIN$N" set nlt_mark = 'U'
where
nlt_mark != 'U'
之所以要做這一步是因為設定這些狀態和刪除$I表是兩個事務。為了避免在更新了狀態位後,沒有刪除$I表的相關資料的情況。
--將N$表的前16000行設定為"M"狀態
update "SUK"."DR$IDX_DOMAIN$N" set nlt_mark = 'M'
where
rownum <= 16000
"M"表示正在被處理。
--更新DR$INDEX的狀態
UPDATE DR$INDEX SET IDX_OPT_TOKEN=:b1,IDX_OPT_TYPE=:b2,IDX_OPT_COUNT=:b3,
IDX_DOCID_COUNT=GREATEST(IDX_DOCID_COUNT - :b3 ,0)
WHERE
IDX_ID = :b5
--提交
commit
--刪除無效的docid對應的$I中資料
delete from "SUK"."DR$IDX_DOMAIN$I"
where
rowid = :rid
--刪除已經優化完成的DOCID
delete from "SUK"."DR$IDX_DOMAIN$N"
where
nlt_mark = 'M'
從以上過程可以看出:oracle優化索引實際上是根據$N表記錄的DOCID刪除$I表對應的資訊,清除$I表的垃圾資料,從而達到提供查詢效能的目的。
實際上,優化索引還執行了合併token的步驟,減少索引的碎片。
在做full方式優化索引時有幾下幾點需要注意:
1)在9ir2以前的版本中,full方式優化索引相當於索引全部刪除了重建;在9ir2後,full方式優化索引不會去重寫已經被優化的記錄。
2)在9ir2前,每次用full方式優化索引最多能處理16000個docid,也就是說每次優化最多能在$I表刪除16000個docid對應的記錄,如果無效doc很多,需要多次執行優化才能完全優化。
在9ir2及以後版本,執行一次full方式優化可以刪除$I表全部的無效資訊,但是,在$N表每次還是最多刪除16000個docid(讓人容易混淆的地方,不明白oracle為什麼這樣做);
如果無效doc很多,那麼在執行完一次full優化後,如果不再產生新的無效doc,那麼,再之後的full優化中,只是刪除$N表的記錄。
3)DR$INDEX中的IDX_OPT_TOKEN為空表示索引已經執行完full方式的優化。
疑問:優化時,為什麼要分成兩個事務?
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/231499/viewspace-63757/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 全文索引的效能優化索引優化
- oracle全文索引之STORAGE PREFERENCEOracle索引
- oracle全文索引之WORDLIST PREFERENCEOracle索引
- Oracle:全文索引Oracle索引
- MongoDB之索引(全文索引)MongoDB索引
- oracle全文索引之STOPLIST_ CTXCAT 索引_INDEX SETOracle索引Index
- Oracle的全文索引Oracle索引
- ZT oracle全文索引Oracle索引
- oracle全文索引之幾個關鍵表Oracle索引
- oracle全文索引之commit與DML操作Oracle索引MIT
- oracle全文索引之如何實現查詢Oracle索引
- oracle全文索引之STOPLIST_4_MULTI_STOPLISTOracle索引
- oracle全文索引之STOPLIST_3_DEFAULT_STOPLISTOracle索引
- oracle全文索引之STOPLIST_2_EMPTY_STOPLISTOracle索引
- oracle全文索引之STOPLIST_1_BASIC_STOPLISTOracle索引
- oracle全文索引之LEXER_4_MULTI_LEXEROracle索引
- oracle全文索引之LEXER_3_DEFAULT_LEXEROracle索引
- oracle全文索引之LEXER_2_CHINESE_LEXEROracle索引
- oracle全文索引之LEXER_1_BASIC_LEXEROracle索引
- oracle全文索引之FILTER_4_PROCEDURE_FILTEROracle索引Filter
- oracle全文索引之FILTER_3_FORMAT_COLUMNOracle索引FilterORM
- oracle全文索引之FILTER_1_NULL_FILTEROracle索引FilterNull
- oracle全文索引之datastore_6_NESTED_DATASTOREOracle索引AST
- oracle全文索引之datastore_5_detail_datastoreOracle索引ASTAI
- oracle全文索引之datastore_4_URL_DATASTOREOracle索引AST
- oracle全文索引之datastore_3_FILE_DATASTOREOracle索引AST
- oracle全文索引之datastore_1_DIRECT_DATASTOREOracle索引AST
- Oracle效能優化之虛擬索引Oracle優化索引
- 基於COST優化,oracle什麼情況不走索引優化Oracle索引
- SQL Server 資料庫優化到底做了什麼SQLServer資料庫優化
- oracle 全文索引的配置Oracle索引
- 【轉載】oracle全文索引的建立和使用Oracle索引
- oracle全文索引之配置全文檢索環境Oracle索引
- oracle 之全文索引表的分割槽交換案例Oracle索引
- oracle全文索引之About_INDEX_THEMES操作Oracle索引Index
- oracle全文索引之datastore_2_MULTI_COLUMN_DATASTOREOracle索引AST
- MSSQL優化之索引優化SQL優化索引
- Oracle優化案例-分割槽索引之無字首索引(六)Oracle優化索引