zoukankan      html  css  js  c++  java
  • oracle全文检索【转】【补】

    全文检索

      oracle对使用几十万以上的数据进行like模糊查询速度极差,包括 like 'AAA%' ,like '%AAA',like '%AAA%',like '%A%A%'的那些模糊查询。网上有很多文章讲到如何提高like查询,提到 like 'AAA%'能够使用到索引,而like '%AAA' ,使用创建反向函数的索引来提高查询效率。

      为了解决大数据情况下的模糊查询速度慢的问题,oracle创建了全文检索技术.

      即通过Oracle专利的词法分析器(lexer),将文章中所有的表意单元(Oracle称为term)找出来,记录在一组以dr$开头的表中,同时记下该term出现的位置、次数、hash值等信息。检索时,Oracle从这组表中查找相应的term,并计算其出现频率,根据某个算法来计算每个文档的得分(score),即所谓的‘匹配率’。而lexer则是该机制的核心,它决定了全文检索的效率。

      oracle有三个基本的分词器

      -- basic_lexer              针对英文,因为英文都用空格和标点分词,纯英文时建议用它

      -- chinese_vgram_lexer      针对中文,支持所有汉字字符集,以字词为单元,分词较机械

      -- chinese_lexer            针对中文,只支持utf8字符集,只认高频常用字词,效率更高,中文时建议用它.

          数数据量达到百万级别以上时,在单列上建立的全文索引相比普通索引的查询速度那将是天差地别的.

    准备工作

      在使用前如果以下语句不能正常执行,那定是DBA没有给该User赋权限.

    1检查和设置数据库角色

      首先检查数据库中是否有CTXSYS用户和CTXAPP脚色。如果没有这个用户和角色,意味着你的数据库创建时未安装intermedia功能。你必须修改数据库以安装这项功能。默认安装情况下,ctxsys用户是被锁定的,因此要先启用ctxsys的用户。

      ctxsys用户默认是被锁定的且密码即时失效,所以我们以sys用户进入em,然后修改ctxsys用户的状态和密码。

    2赋权 

      以abc用户下的tbl_my_lex表为例.

      先以sys用户DBA身份登录,对abc赋resource,connect权限:

    GRANT resource, connect  to abc;
    

      

     

    再以ctxsys用户登录并对abc用户赋权

    GRANT  ctxapp  to  abc;
    
    GRANT execute ON ctxsys. ctx_cls  TO abc;
    
    GRANT execute ON ctxsys. ctx_ddl  TO abc;
    
    GRANT execute ON ctxsys. ctx_doc  TO abc;
    
    GRANT execute ON ctxsys. ctx_output TO abc;
    
    GRANT execute ON ctxsys. ctx_query TO abc;
    
    GRANT execute ON ctxsys. ctx_report  TO abc;
    
    GRANT execute ON ctxsys. ctx_thes  TO abc;
    
    GRANT execute ON ctxsys. ctx_ulexer TO abc;
    

      

     

    基本语法

    然后以abc用户登录 :

    conn  abc/abc;
    

      

    --------------------------------------------------------------------------------------

    -- 建表
    
    Create table tbl_my_lex (id number primary key, info varchar2(1000));
    
    Insert into tbl_my_lex values (1, 'this is a example for the basic_lexer');
    
    Insert into tbl_my_lex values (2, 'he following example sets Printjoin characters ');
    
    Insert into tbl_my_lex values (3, 'To create the INDEX with no_theme indexing ');
    
    Insert into tbl_my_lex values (4, '中华人民共和国');
    
    Insert into tbl_my_lex values (5, '中国淘宝软件');
    
    Insert into tbl_my_lex values (6, '测试basic_lexer 是否支持中文');
    
    Commit;
    

      

    --------------------------------------------------------------------------------------

    -- 创建一个名为my_chinese_lexer的chinese_lexer格式的分词器
    
    Begin
    
    ctx_ddl.create_preference('my_chinese_lexer', 'chinese_lexer');
    
    End;
    
    /
    

      

    --------------------------------------------------------------------------------------

    -- 对tbl_my_lex这张表的info列的信息建立一个名为IDX_TBL_COL的索引
    
    Create index IDX_TBL_COL on tbl_my_lex (info) indextype is ctxsys.context parameters ('lexer my_chinese_lexer');
    

      

    --------------------------------------------------------------------------------------

    -- 以刚才建立的全文索引方式进行查询
    
    Select * from tbl_my_lex where contains(info, '中国') > 0;
    

      

    --------------------------------------------------------------------------------------

    ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑如果表是死的不会增删,那么到此为止就够了↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

    ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓如果表是活的,会动态增加,那么继续往下看↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

    -- 存过1,同步索引,即把新增的记录,添加到索引的检索范围
    
    begin
    
    ctx_ddl.sync_index('IDX_TBL_COL'); 
    
    end;
    
    /
    
    -- 意为如果新增一行记录,不用ctx_ddl .sync_index,
    
    -- 直接 Select * from tbl_my_lex where contains(info, '中国') > 0;查到的结果是不会改变的
    

      

    --------------------------------------------------------------------------------------

    -- 存过2,同步索引,即把删除的记录,踢出索引的检索范围
    
    begin
    
    ctx_ddl.optimize_index('INX_CUSTOMINFO_ADDR_DOCS', 'FAST');
    
    end;
    
    /
    
    -- 意为如果删除一行记录,不用ctx_ddl .sync_index,
    
    -- 直接 Select * from tbl_my_lex where contains(info, '中国') > 0;查到的结果是不会改变的
    

      

    --------------------------------------------------------------------------------------

    -- 网上文章说: 65万记录的一个表建立索引只需要20分钟,同步一次约1分钟
    
    -- 所以对存过1和存过2作job定时是很有必要的.
    

      

    -- 其它语句

    --------------------------------------------------------------------------------------

    -- 删除一个名为my_chinese_lexer的chinese_lexer格式的分词器
    
    Begin
    
    ctx_ddl.drop_preference('my_chinese_lexer');
    
    End;
    
    /
    

      

    --------------------------------------------------------------------------------------

    DROP  INDEX  IDX_TBL_COL  FORCE; -- 强行删除索引
    

      

    --------------------------------------------------------------------------------------

    参考 

    http://chaoji-liangbin.blog.163.com/blog/static/252392122010915101351354/

    http://blog.chinaunix.net/uid-14107-id-2844042.html

    http://blog.itpub.net/15962/viewspace-1005675/

  • 相关阅读:
    【Android】12.0 UI开发(三)——列表控件ListView的简单实现2
    【Android】11.0 UI开发(二)——列表控件ListView的简单实现1
    【Android】10.0 UI开发——如何编写程序界面、常见控件的使用
    【转载】从创业者角度看《印度合伙人 Padman》后的一点感受
    【代码笔记】Java常识性基础补充(二)——数组、ArrayList集合、ASCII编码、 eclipse基础操作、eclipse调试、eclipse项目导入、eclipse快捷键
    Android 实现高斯模糊效果和圆角图片
    Android 获取当前系统时间
    Android RecycleView悬浮按钮点击返回顶部
    eclipse连接mysql
    mysql的增删改查语句
  • 原文地址:https://www.cnblogs.com/whatlonelytear/p/4923264.html
Copyright © 2011-2022 走看看