欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

Oracle全文索引使用方法

程序员文章站 2022-05-07 18:38:03
...

Oracle全文索引是一种用空间换取时间的一种技术,再加上dml操作不能自动同步到索引,需要手动定期维护,所以适用场景也不是很广泛

接近千万数据表中有个name字段,存放中文名称,现在需要根据name字段模糊匹配查询数据,一般的做法是对name字段建立b*tree索引,查询用like'%name%',但是经过测试,这种写法没有走索引,而是全表扫描,可想而知性能有问题。所以采用了Oracle提供的全文索引技术,下面详细介绍下如何使用全文索引。

相关阅读:

由Oracle索引来理解ArcSDE索引

Oracle索引技术之如何建立最佳索引

Oracle索引列NULL值引发执行计划该表的测试示例

Oracle索引 主键影响查询速度

Oracle索引扫描

1.使用前提

1) 检查数据库中是否有CTXSYS用户(从dba_users)和CTXAPP角色(dba_roles)。如果没有这个用户和角色,意味着你的数据库创建时未安装intermedia功能。你必须修改数据库以安装这项功能。

2) 把CTXAPP角色赋于当前用户: GRANT CTXAPP TO 当前用户;

3) 把CTX_DDL的执行权限赋于当前用户: GRANT EXECUTE ON CTX_DDL TO 当前用户;

2.创建分析器

oracle text的分析器,将需要检索的记录,按照一定的方式进行词组拆分,然后存放在索引表中。检索的时候根据索引表中存放的拆分词组,对传入的关键字进行匹配,并返回匹配结果。

oracle text中的分析器有3种:

1) basic_lexer:针对英文,只能根据空格和标点来进行拆分。比如“中国深圳”,,只能拆分为“中国深圳”一个词,根据“中国”或者“深圳”就搜索不到。

2) chinese_vgram_lexer:专门的汉语分析器,按字单元进行拆分,比如“中国深圳”,可以拆分为“中”、“中国“、”国深”、“深圳”、“圳”五个词组。这种方式的好处是能够将所有有可能的词组全部保存进索引表,使得数据不会遗漏,但是效率上来说就差强人意了。

3) chinese_lexer:一种新的汉语分析器,能够认识大部分常用的汉语词汇,较与chinese_vgram_lexer机械式的拆分,能够按常用词汇进行拆分存储。比如“中国深圳”,只会被拆分为“中国”、“深圳”两个词组。

具体语法为:

ctx_ddl.drop_preference('testlex');--删除

ctx_ddl.create_preference('testlex','CHINESE_LEXER');--创建一个“CHINESE_LEXER”分析器,名称为“testlex”

3.创建过滤词组

假设根据公司名称进行检索,一般情况下我们不希望,当输入“公司”、“股份公司”、“有限公司”等能够检索出来结果,所以需要对这些关键字进行过滤。当然如果没有这种特殊的需求,可以不用创建过滤词组的。

1) 创建一个过滤器,名称为“teststoplist”

exec ctx_ddl.create_stoplist('teststoplist');

2) 添加自定义需要过滤的词组,以下内容的意思是“公司”、“股份公司”、“有限公司”这些词组不会创建索引,不会被检索到。

ctx_ddl.add_stopword('teststoplist','有限公司');

ctx_ddl.add_stopword('teststoplist','公司');

ctx_ddl.add_stopword('teststoplist','股份公司');

4.创建索引

create index idx_test on test(name) indextype is CTXSYS.CONTEXT parameters('lexertestlex stoplistteststoplist');

以上语句的意思是在test表name字段上创建全文索引,索引类型为CTXSYS.CONTEXT,用到了上面创建的分析器“testlex”、过滤词组“teststoplist”。

创建完索引之后,可以看到生成了如下几个表:dr$idx_test$i;dr$idx_test$k;dr$idx_test$n;dr$idx_test$r;其中dr$idx_test$i表存放的就是name字段分词后的数据。

5.使用索引

oracle全文索引使用时,sql语句必须使用contains关键字,具体如下:

select * from test where contains(name,'深圳') > 0;

如果需要根据匹配程度来排序,如下:

select score(1),t.* from test t where contains(name,'深圳',1)>0 order by score(1) desc;

6.索引维护

对表的dml操作是不会更新全文索引的,这个也是全文索引的一个特点,索引我们必须手动去维护索引,具体写法如下:

exec ctx_ddl.sync_index('IDX_TEST');--同步索引,将新的数据同步到索引

exec ctx_ddl.optimize_index('IDX_TEST','FULL');--优化索引,清楚已删除的数据

总结:Oracle全文索引是一种用空间换取时间的一种技术,再加上dml操作不能自动同步到索引,需要手动定期维护,所以适用场景也不是很广泛。因此,选择使用时请慎重。