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:全文索引Oracle索引
- Oracle的全文索引Oracle索引
- oracle全文索引之commit與DML操作Oracle索引MIT
- oracle全文索引之幾個關鍵表Oracle索引
- oracle全文索引之如何實現查詢Oracle索引
- oracle全文索引之配置全文檢索環境Oracle索引
- Oracle優化案例-分割槽索引之無字首索引(六)Oracle優化索引
- 為什麼ElasticSearch比MySQL更適合全文索引ElasticsearchMySql索引
- MySQL索引系列:全文索引MySql索引
- MySQL 為什麼全文索引查中文找不結果MySql索引
- MySQL調優之索引優化MySql索引優化
- SQL優化之統計資訊和索引SQL優化索引
- MySQL優化之索引解析MySql優化索引
- Mysql索引優化之索引的分類MySql索引優化
- MySQL全文索引的使用MySql索引
- Oracle優化案例-正確的使用索引(二)Oracle優化索引
- Oracle優化案例-自定義函式索引(五)Oracle優化函式索引
- 使用Elasticsearch的動態索引和索引優化Elasticsearch索引優化
- MySQL-效能優化-索引和查詢優化MySql優化索引
- mysql索引的使用和優化MySql索引優化
- MySQL效能優化之索引設計MySql優化索引
- 理解索引:索引優化索引優化
- 非同步函式async await在wpf都做了什麼?非同步函式AI
- SQL優化案例-分割槽索引之無字首索引(六)SQL優化索引
- Android 效能優化(十二)之我為什麼寫效能優化Android優化
- Oracle索引梳理系列(六)- Oracle索引種類之函式索引Oracle索引函式
- mysql索引優化和TCP協議MySql索引優化TCP協議
- MySQL優化學習筆記之索引MySql優化筆記索引
- 【MySQL】三、效能優化之 覆蓋索引MySql優化索引
- MySQL優化之覆蓋索引的使用MySql優化索引
- 《MySQL慢查詢優化》之SQL語句及索引優化MySql優化索引
- mysql中文全文索引的記錄MySql索引
- 【SqlServer】管理全文索引(FULL TEXT INDEX)SQLServer索引Index
- oracle組合索引什麼情況下生效?Oracle索引
- oracle之 反向鍵索引Oracle索引
- Vue 修改成功之後我做了什麼Vue
- 加速Spring現代化,我們做了什麼?Spring
- Elasitcsearch索引優化索引優化