oracle索引实现方式,oracle全文索引之如何实现查询

本文通过两个实验展示了Oracle Text搜索的工作原理。实验一说明了直接查询的执行流程;实验二则探讨了先删除(或更新)后查询时,Oracle如何处理被删除的数据,涉及DR$DELETE表的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先介绍两个脚本: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如何知道当前会话有没有删除或者修改数据?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值