oracle全文索引之如何實現查詢
oracle全文索引有很多種查詢方式,最常用的可能是contains。下面就contains簡單闡述oracle全文檢索執行查詢的執行機制。
先介紹兩個指令碼:begin_trace、end_trace是我為了方便檢視trace檔案寫的指令碼。程式碼如下:
-- run in SQL*Plus --
-- begin_trace ----
set termout off
set heading off
set verify off
set feedback off
alter session set timed_statistics=true;
alter session set events '10046 trace name context forever,level 12';
-- run in SQL*Plus --
-- end_trace ----
alter session set events '10046 trace name context off';
column trace_file_name new_val f
column tk_name new_val tk
select
d.value||b.is_win||lower(rtrim(i.instance, chr(0)))||'_ora_'||p.spid||'.trc' trace_file_name
from
( select p.spid
from v$mystat m,v$session s,v$process p
where m.statistic# = 1 and s.sid = m.sid and p.addr = s.paddr) p,
( select t.instance from v$thread t,v$parameter v
where v.name = 'thread' and (v.value = 0 or t.thread# = to_number(v.value))) i,
( select value from v$parameter where name = 'user_dump_dest') d,
(select DECODE(count(*),0,'/','') is_win from v$version where upper(banner) like '%WINDOWS%') b;
select value||b.is_win||'tk.prf' tk_name
from v$parameter v ,
(select DECODE(count(*),0,'/','') is_win from v$version where upper(banner) like '%WINDOWS%') b
where name = 'user_dump_dest';
set termout on
set heading on
set verify on
set feedback off
host tkprof &f &tk
edit &tk
實驗一:直接查詢
> @begin_trace
> select * from t_domain where contains(doc,'shenzhen') >0;
5 this is shenzhen
> @end_trace
產?膖race內容比較多,這裡把最主要的地方摘取出來:
--發出查詢
select *
from
t_domain where contains(doc,'shenzhen') >0
BEGIN :p := CTX_QUERY.PREFERENCE;END;
SELECT /*+ INDEX(i) */ TOKEN_FIRST,TOKEN_LAST,TOKEN_COUNT,ROWID
FROM
"SUK"."DR$IDX_DOMAIN$I" i WHERE TOKEN_TEXT = :word AND TOKEN_TYPE = :wtype
ORDER BY TOKEN_TEXT, TOKEN_TYPE, TOKEN_FIRST
SELECT TOKEN_INFO
FROM
"SUK"."DR$IDX_DOMAIN$I" WHERE ROWID = :rid
select data
from
"SUK"."DR$IDX_DOMAIN$R" where row_no = :row_no
從trace中的sql可以知道查詢的執行流程:
1、首先使用者發出包含contains的查詢
2、根據關鍵字在$I表中得到滿足條件的rowid
3、根據上一步得到的rowid得到TOKEN_INFO,TOKEN_INFO中包含了滿足條件的docid、row_no等資訊
4、oracle根據這些資訊在$R表中取出基表中滿足查詢條件的rowid,然後返回給原始的查詢語句
5、最終oracle根據這些rowid取出使用者需要的資料。
---------------------------------------------------------------
實驗二、先刪除(或者更新),再查詢
> delete from t_domain where rownum=1;
已刪除 1 行。
> @begin_trace
> select * from t_domain where contains(doc,'shenzhen') >0;
> @end_trace
注意:不要提交
摘錄trace中主要的sql如下:
select *
from
t_domain where contains(doc,'shenzhen') >0
SELECT DEL_DOCID
FROM
DR$DELETE WHERE DEL_IDX_ID = :iid and DEL_ixp_id = :ipid ORDER BY DEL_IDX_ID,
DEL_DOCID DESC
BEGIN :p := CTX_QUERY.PREFERENCE;END;
SELECT /*+ INDEX(i) */ TOKEN_FIRST,TOKEN_LAST,TOKEN_COUNT,ROWID
FROM
"SUK"."DR$IDX_DOMAIN$I" i WHERE TOKEN_TEXT = :word AND TOKEN_TYPE = :wtype
ORDER BY TOKEN_TEXT, TOKEN_TYPE, TOKEN_FIRST
SELECT TOKEN_INFO
FROM
"SUK"."DR$IDX_DOMAIN$I" WHERE ROWID = :rid
從trace中的sql可以看出,這個執行流程和實驗一不一樣。
在這個實驗中,多了從DR$DELETE中查詢docid這一步。
我們知道,DR$DELETE是儲存當前會話在修改資料而沒有提交時被刪除的docid。
1、首先使用者發出包含contains的查詢
2、如果發生了資料刪除(更新),oracle先從DR$DELETE中得到在當前會話中被刪除的docid
3、再根據關鍵字在$I表中得到滿足條件的rowid
4、根據上一步得到的rowid得到TOKEN_INFO,TOKEN_INFO中包含了滿足條件的docid、row_no等資訊
5、在上一步得到的結果中排除從DR$DELETE得到的docid。
6、oracle根據這些資訊在$R表中取出基表中滿足查詢條件的rowid,然後返回給原始的查詢語句
7、最終oracle根據這些rowid取出使用者需要的資料。
其中:第四步在trace中並沒有得到反映,但從oracle官方文件和實際測試中得到驗證。
不明之處:
1、$K表會在什麼情況下?
oracle文件說到:
There are two sorts of index lookup used in interMedia Text - normal and functional lookups.
The normal lookup effectively says "give me all the rowids that satisfy my text criteria", whereas the functional lookup says "does row satisfy my text criteria?"
In the case of a functional lookup, there is no need for any special processing.
Functional lookup uses the $K table, and this table is updated immediately the record is changed.
也就是說在functional lookup會用到$K表。
上面查詢舉到的例子說的都是normal lookup。那什麼是functional lookup呢?
2、oracle如何知道當前會話有沒有刪除或者修改資料?
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/231499/viewspace-63756/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 全文索引和查詢概念索引
- mysql多表查詢如何實現MySql
- 如何實現查詢介面的所有實現類
- 如何實現引數級聯查詢
- 如何實現模糊查詢時間段
- 利用Oracle的全文索引實現切詞功能Oracle索引
- oracle全文索引之STORAGE PREFERENCEOracle索引
- oracle全文索引之WORDLIST PREFERENCEOracle索引
- SQL如何實現查詢節點依賴SQL
- 如何優雅地實現分頁查詢
- Access查詢實現Mysql的 limit 查詢MySqlMIT
- oracle中connect by prior實現遞迴查詢Oracle遞迴
- Oracle分頁查詢之order byOracle
- oracle語法相容--如何透過with recursive語法來實現oracle的分層查詢Oracle
- Oracle如何查詢當前LockOracle
- java實現折半查詢。Java
- 查詢演算法集:順序查詢、二分查詢、插值查詢、動態查詢(陣列實現、連結串列實現)演算法陣列
- 查詢之折半查詢
- 【SQL】Oracle查詢轉換之 OR用法SQLOracle
- 【SQL】Oracle查詢轉換之物化檢視查詢重寫SQLOracle
- 第 34 題:如何實現二叉查詢樹?
- SSH:hiberate實現資料的查詢(單查詢和全查詢)
- 如何使用 Milvus 向量資料庫實現實時查詢資料庫
- oracle 10.2.0.1 rac發現sql查詢hang之gc cr requestOracleSQLGC
- indexdb實現分頁查詢Index
- 折半查詢(C++實現)C++
- mysql實現隨機查詢MySql隨機
- Oracle 查詢Oracle
- ORACLE_OCP之SQL_子查詢OracleSQL
- Laravel Query Builder 複雜查詢案例:子查詢實現分割槽查詢 partition byLaravelUI
- 查詢皮膚中如何實現兩個 select 下拉框的關聯查詢?
- 【SQL查詢】集合查詢之INTERSECTSQL
- oracle全文索引之幾個關鍵表Oracle索引
- oracle全文索引之commit與DML操作Oracle索引MIT
- oracle全文索引之STOPLIST_4_MULTI_STOPLISTOracle索引
- oracle全文索引之STOPLIST_3_DEFAULT_STOPLISTOracle索引
- oracle全文索引之STOPLIST_2_EMPTY_STOPLISTOracle索引
- oracle全文索引之STOPLIST_1_BASIC_STOPLISTOracle索引