oracle全文索引使用方法

    接近千万数据表中有个name字段,存放中文名称,现在需要根据name字段模糊匹配查询数据,一般的做法是对name字段建立b*tree索引,查询用like'%name%',但是经过测试,这种写法没有走索引,而是全表扫描,可想而知性能有问题。所以采用了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操作不能自动同步到索引,需要手动定期维护,所以适用场景也不是很广泛。因此,选择使用时请慎重。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值