如何更好地使用Oracle全文索引

不使用Oracle text函数在Oracle数据库中搜索文本的方法有很多,可以使用标准的INSTR函数和LIKE运算符来实现。

SELECT * FROM my text WHERE INSTR(the text,' Oracle ')& gt;0;

SELECT * FROM mytext,其中文本类似于“% Oracle %”;

在许多情况下,使用instr和like是理想的,特别是当搜索只跨越一个小表时。但是这些文本定位方式会导致全表扫描,耗费资源,搜索功能非常有限。所以在搜索海量文本数据时,建议使用oralce提供的全文搜索功能,建立全文搜索。步骤1:检查并设置数据库角色。首先,检查数据库中是否有CTXSYS用户和CTXAPP基石。如果没有这个用户和角色,这意味着在创建数据库时没有安装intermedia函数。您必须修改数据库才能安装此功能。默认情况下,ctxsys的用户是锁定的,因此应该首先启用ctxsys的用户。第二步:将ctxsys用户下ctx_ddl的执行权限授予想要使用全文索引的用户,例如:

将ctx_ddl上的execute授予pomoho

步骤3:设置词法分析器(lexer)

Oracle实现全文检索,其机制其实很简单。即通过甲骨文专利的词法分析器(lexer)找出文章中所有的表意单位(甲骨文称之为$ term),并记录在一组以dr$开头的表格中,同时记录$ term的位置、频率、哈希值等信息。在搜索时,Oracle从这组表中查找相应的$ term,计算其出现频率,并根据一种算法计算每个文档的得分,这就是所谓的‘匹配率’。Lexer是这个机制的核心,决定了全文检索的效率。Oracle为不同的语言提供了不同的lexer,我们通常可以使用其中的三种:

N basic_lexer:针对英语。它可以根据空格和标点符号将英语单词从句子中分离出来,还可以自动将一些出现过于频繁、已经失去检索意义的单词视为‘垃圾’,如if、is等。,处理效率高。然而,这个词用在汉语中存在许多问题。因为它只识别空格和标点符号,而中文句子中通常没有空格,所以它会把整个句子当作一个$ term,事实上它会失去检索能力。以“中国人民站起来了”这句话为例。basic_lexer分析的结果只有一个$ term,就是“中国人民站起来了”。如果此时搜索“中国”,将无法检索到相关内容。

N chinese_vgram_lexer:支持所有中文字符集的专用中文分析器(ZHS 16 GB 231280 zhs 16 gbk zht 32 euchzht 16 big 5 zht 32 triszht 16 ms win 950 zht 16 hkk)。分析器以词为单位分析汉语句子。“中国人民站起来了”这句话,将被它分析为:“中国”、“中国人”、“中国人”、“人民”、“人民站起来”、“起来”、“来了”、“来了”。可以看出,这种分析方法,实现算法非常简单,可以实现‘一网打尽’,但效率并不尽如人意。

N chinese_lexer:这是一个新的中文分析器,只支持utf8字符集。正如我们上面看到的,分析器中文vgram lexer是非常机械的,因为它不知道常用的中文单词。比如上面的‘人站’和‘站起来’在中文里永远不会单独出现,所以这种$ term是没有意义的,会影响效率。chinese_lexer最大的改进是分析器可以理解大多数常用的中文单词,因此可以更高效地分析句子。以上两个傻逼单位不会再出现,大大提高了效率。但它只支持utf8。如果你的数据库是zhs16gbk字符集,那就只能用傻逼的中文vgram lexer了。

如果不做任何设置,Oracle默认使用解析器basic_lexer。要指定使用哪个词法分析器,可以这样做:

首先,在当前用户下创建一个首选项(例如,在pomoho用户下执行下面的语句)。

exec CTX _ DDL . create _ preference(' my _ lexer ',' Chinese _ vgram _ lexer ');

其次,在建立全文索引时,指定所使用的词法分析器:

在mytable(mycolumn)上创建索引myindex索引类型为ctxsys.context

参数(' lexer my _ lexer ');

这样建立的全文索引将使用chinese_vgram_lexer作为解析器。

第四步:建立索引。

使用以下语法建立全文索引

创建索引[架构。]架构上的索引。]表(列)索引类型为ctxsys.context [ONLINE]

LOCAL[(PARTITION[PARTITION][PARAMETERS(' paramstring ')]

[,PARTITION[PARTITION][PARAMETERS(' paramstring ')]]]]

[PARAMETERS(paramstring)][PARALLEL n][UNUSABLE];

示例:

在pubmenu上创建索引CTX _ idx _ menuname(menuname)

indextype是ctxsys.context参数(' lexer my_lexer ')

使用索引

使用全文索引很简单,可以通过以下方式实现:

select * from pub menu where contains(menu,'上传图片')> 0

全文索引的类型

已建立的Oracle Text索引称为域索引,它包括四种索引类型:

l上下文

2 CTXCAT

3 CTXRULE

4 CTXXPATH

根据您的应用程序和文本数据类型,您可以选择任何一种。

为多个字段建立全文索引

很多时候,需要从多个文本字段中查询符合要求的记录。这时候就需要为多个字段建立全文索引。例如,如果需要从pmhsubjects的subjectname和briefintro中进行全文检索,则需要执行以下步骤:

建议首选多字段索引

以ctxsys身份登录并执行:

EXEC CTX _ DDL . create _ preference(' CTX _ idx _ subject _ pref ',

多列数据存储');

建立与首选项相对应的字段值(以ctxsys身份登录)

EXEC CTX _ DDL . set _ attribute(' CTX _ idx _ subject _ pref ',' columns ',' subjectname,brief intro ');

建立全文索引

在pmhsubjects(subjectname)上创建索引ctx_idx_subject

INDEXTYPE ISctxsys。上下文参数('数据存储CTX sys . CTX _ idx _ subject _ pref lexer my _ lexer ')

使用索引

select * from pmh subjects where contains(主题名,“李宇春”)> 0

全文索引的维护

为了CTXSYS。上下文索引,在应用程序对基表执行DML操作后,需要维护基表的索引。索引维护包括索引同步和索引优化。

索引建立后,我们可以发现Oracle在这个用户下自动生成了下面的表:(假设索引名为myindex):

$myindex$I博士,$myindex$K博士,$myindex$R博士,$myindex$N博士,其中表I最重要。您可以查看该表,了解它包含的内容:

SELECT token_text,token _ count FROM dr $ I _ rsk 1 $ I其中ROWNUM & lt= 20;

这里就不列举查询了。我拿了。如您所见,保存在这个表中的实际上是Oracle在分析您的文档后生成的$ term记录,包括$ term的位置、频率和哈希值。当文档内容发生变化时,可想而知,这个I表的内容也应该发生相应的变化,以保证Oracle在做全文检索时能够正确地检索到内容(因为所谓的全文检索其实就是查询这个表的核心)。这使用了sync(同步)和optimize(优化)。

Sync:将新的$ term保存到I表中;

优化:清除I表的垃圾,主要是删除I表中已删除的$ term。

当基表中的索引文档被插入、更新或删除时,基表的更改不会立即影响索引,直到索引被同步。您可以查询视图CTX _用户_待定来查看相应的更改。例如:

SELECT pnd_index_name,pnd_rowid,

TO _ CHAR(PND _时间戳,' dd-mon-yyyy hh24:mi:ss ')时间戳

来自ctx _ user _ pending

该语句的输出类似于以下内容:

PND索引名称PND ROWID时间戳

- - -

MYINDEX aaadxnaabaaas 3 saac 06-oct-1999 15:56:50

同步和优化方法:可以使用Oracle提供的ctx_ddl包来同步和优化索引。

1.对于CTXCAT类型的索引,当对基表执行DML操作时,Oracle会自动维护索引。对文档的更改会立即反映在索引中。CTXCAT是交易形式的索引。

索引的同步

在插入、修改和删除基表后同步索引。建议使用sync来同步索引。语法:

ctx _ ddl.sync _索引(

VARCHAR2中的idx_name默认为空

VARCHAR2中的内存默认为空,

VARCHAR2中的part_name默认为空

parallel_degree IN NUMBER默认1);

Idx_name索引名称

Memory指定同步索引所需的内存。默认值是系统参数DEFAULT_INDEX_MEMORY。

指定大内存可以加快索引效率和查询速度,索引碎片少。

Part_name同步哪个分区索引。

并行度并行同步索引。设置平行度。

例如:

同步索引myindex:exectx _ DDL . sync _ index(' myindex ');

实现建议:建议通过oracle的job同步索引。

索引优化

频繁的索引同步会导致上下文索引碎片化。索引碎片严重影响查询的响应速度。可以定期优化索引,减少碎片,减小索引大小,提高查询效率。

从表中删除文本后,Oracle Text会标记删除的文档,但不会立即修改索引。因此,现有的文档信息占用了不必要的空间,导致了额外的查询成本。您必须在完全模式下优化索引,并从索引中删除无效的旧信息。这个过程叫做垃圾处理。当你经常更新和删除表格文本数据时,垃圾处理是必要的。

exec CTX _ DDL . optimize _ index(' myidx ',' full ');

建议:每天在系统空闲时优化全文索引,提高检索效率。

P.s .时序优化指数

3.定时优化同步域索引。

创建计划任务,定期优化和同步域索引。

SQL & gt创建或替换过程hsp_sync_index为

2开始

3 CTX _ DDL . sync _ index(' id _ cont _ msg ');

4结束;

5 /

程序已创建。

耗时:00:00:00.08

SQL & gt可变工单编号;

SQL & gt开始

2 DBMS_JOB。提交(:作业号,' HSP _ sync _ index();',

3 SYSDATE,' SYSDATE+(1/24/4)');

4提交;

5结束;

6 /

PL/SQL过程已成功完成。

耗时:00:00:00.27

SQL & gt将过程hsp_optimize_index创建或替换为

2开始

3 CTX _ DDL . optimize _ index(' id _ cont _ msg ',' FULL ');

4结束;

5 /

SQL & gt可变工单编号;

SQL & gt开始

2 DBMS_JOB。SUBMIT(:jobno,' HSP _ optimize _ index();',

3 SYSDATE,' SYSDATE+1 ');

4提交;

5结束;

6 /

程序已创建。

耗时:00:00:00.03

PL/SQL过程已成功完成。

耗时:00:00:00.02

SQL & gt