【问题标题】:How to create text index for '%abc%' search?如何为“%abc%”搜索创建文本索引?
【发布时间】:2011-12-06 15:46:24
【问题描述】:

我想索引像x like '%abc%'这样的查询

如果我有如下表格

create table t
(
  data varchar(100)
);

我想创建一个索引,以便能够有效地执行以下操作:

select * from t where contains('%abc%');

还有这个:

select * from t where contains('abc%');

我还希望实时更新此表。

如何创建这样的索引? (我感觉我需要一个ctxcat 索引,但我对需要提供哪些选项感到困惑)

我使用的是 Oracle 10g。

【问题讨论】:

    标签: sql oracle full-text-search indexing


    【解决方案1】:

    我会使用这个(设置你的最小和最大长度以适当的值)

    BEGIN
        ctx_ddl.create_preference  ('FT_WL', 'BASIC_WORDLIST');
        ctx_ddl.set_attribute      ('FT_WL', 'substring_index',   'YES');
        ctx_ddl.set_attribute      ('FT_WL', 'prefix_index',      'YES');
        ctx_ddl.set_attribute      ('FT_WL', 'prefix_min_length', 1);
        ctx_ddl.set_attribute      ('FT_WL', 'prefix_max_length', 6);
      END;
    
    CREATE INDEX fulltext_idx ON tmp_fulltext (fulltext)
     INDEXTYPE IS CTXSYS.CTXCAT
     PARAMETERS ('WORDLIST FT_WL')
    

    这里解释参数Oracle Text Reference

    并查看有关如何管理刷新以及索引可能不会比具有高基数数据的完整扫描更快的问题:

    PL/SQL Performance Tuning for LIKE '%...%' Wildcard Queries

    【讨论】:

    • 感谢您的回答。只是几个问题:prefix_index 用于 abc% 查询,'substring_index' 用于%abc% 查询?并且默认情况下子字符串索引是否索引所有子字符串?另外,我如何使用这个索引? contains(col, '%abc%')contains(col, 'abc%') 会成功吗?
    • 是的,这些搜索会起作用,已经更新了一个可以比我更好地解释它的链接,但本质上这些参数用于提高该类型搜索的性能。
    【解决方案2】:

    是的,您需要先创建环境,然后才能创建域索引。您需要拥有ctxsys 用户和必要的ctxapp 权限才能创建它。 Follow the steps explained in this link to have one for your environment。默认情况下,安装 Oracle 时不会创建此用户。

    一旦您拥有所有授权和软件包,您就可以创建首选项和索引,如图所示。

    SQL> begin
      2  ctx_ddl.create_preference('SUBSTRING_PREF', 'BASIC_WORDLIST');
      3  ctx_ddl.set_attribute('SUBSTRING_PREF', 'SUBSTRING_INDEX','TRUE');
      4  end;
      5  /
    

    现在如图所示创建一个域索引。

     SQL> create index test_idx on test(object_name)
       2  indextype is ctxsys.context parameters ('wordlist SUBSTRING_PREF MEMORY 50M');
    
    Index created.
    
    select * from test where contains( object_name,'%EXEC%') > 0;
    

    请参阅下面的链接,该链接通过执行计划解释了这一点。 2018 年更新:很遗憾,原始链接已失效,并且未在 archive.org 上备份。

    http://www.oraclebin.com/2012/12/oracle-text-and-domain-indexes.html

    【讨论】:

      【解决方案3】:

      如果您的数据库很大,请查看您的问题,然后您可以使用Sphinx Search

      Sphinx 是一款开源全文搜索服务器,从头开始设计时就考虑到了性能、相关性(又称搜索质量)和集成简单性。它是用 C++ 编写的,适用于 Linux(RedHat、Ubuntu 等)、Windows、MacOS、Solaris、FreeBSD 和其他一些系统

      【讨论】:

      • 这看起来很有趣,但遗憾的是我坚持使用 Oracle 10g。
      【解决方案4】:

      只有在服务器上有 intermedia/Oracle Text 选项时,您才能在 Oracle 中执行此操作...

      对于您的示例,您可以使用

      create index t_index_data on t(data) 
      indextype is ctxsys.context 
      parameters ('DATASTORE CTXSYS.DEFAULT_DATASTORE');
      

      我不确定您是否需要将类型从 varchar2(100) 更改为 clob

      有关此类索引的详细信息和选项/示例,请参阅http://download.oracle.com/docs/cd/A91202_01/901_doc/text.901/a90122/ind4.htm

      【讨论】:

      • 您确定这会索引子字符串吗?我阅读了文档,似乎我需要一个“首选项”“SUBSTRING_INDEX”之类的东西。你能给出一个代码示例来做我正在寻找的包括子字符串索引吗?
      • 您的偏好可能是正确的 - 我没有提供这些选项的 Oracle 服务器,因此我无法对其进行测试...
      猜你喜欢
      • 2021-11-13
      • 2011-03-20
      • 2016-06-09
      • 1970-01-01
      • 2020-07-28
      • 1970-01-01
      • 1970-01-01
      • 2011-01-08
      • 1970-01-01
      相关资源
      最近更新 更多