当前位置: 首页 > 面试题库 >

Oracle:带条件的全文搜索

杜曜灿
2023-03-14
问题内容

我创建了如下的Oracle Text索引:

create index my_idx on my_table (text) indextype is ctxsys.context;

然后,我可以执行以下操作:

select * from my_table where contains(text, '%blah%') > 0;

但是,可以说我们在此表中还有另一列,例如group_id,我想改为执行以下查询:

select * from my_table where contains(text, '%blah%') > 0 and group_id = 43;

使用上述索引,Oracle将必须搜索包含的所有项目,'blah'然后检查所有group_id

理想情况下,我宁愿只使用来搜索项目group_id = 43,因此我想要这样的索引:

create index my_idx on my_table (group_id, text) indextype is ctxsys.context;

有点像普通索引,因此可以对每个进行单独的文本搜索group_id

有没有一种方法可以在Oracle中做这样的事情(如果很重要,我将使用10g)?

编辑(说明)

考虑一个具有一百万行和以下两列的表,A以及B均为数字。可以说有500个不同的值A和2000个不同的值B,并且每一行都是唯一的。

现在让我们考虑 select ... where A = x and B = y

在索引AB单独至于我可以告诉做一个索引搜索B,它会返回500个的不同行,然后做一个连接/扫描这些行。无论如何,至少要查看500行(除了数据库很幸运并能尽早找到所需的行之外)。

索引启用(A,B)更为有效,但它会在一次索引搜索中找到一行。

group_id我觉得在文本上放置单独的索引只会给查询生成器留下两个选项。

(1)使用group_id索引,并在所有结果行中扫描文本。
(2)使用文本索引,并在所有结果行中扫描group_id
(3)使用两个索引,并进行联接。

而我想要:

(4)使用(group_id, "text")索引查找特定索引下的group_id文本索引,然后扫描该文本索引以查找所需的特定行/行。无需扫描,检查或合并,就像在上使用索引时一样(A,B)


问题答案:

Oracle文本

1-您可以通过使用FILTER
BY
创建CONTEXT索引来提高性能:

create index my_idx on my_table(text) indextype is ctxsys.context filter by group_id;

在我的测试中,filter by绝对可以提高性能,但是仅在group_id上使用btree索引仍然稍快一些。

2-CTXCAT索引使用“子索引”,并且工作方式类似于多列索引。这似乎是您要寻找的选择(4):

begin
  ctx_ddl.create_index_set('my_table_index_set');
  ctx_ddl.add_index('my_table_index_set', 'group_id');
end;
/

create index my_idx2 on my_table(text) indextype is ctxsys.ctxcat
    parameters('index set my_table_index_set');

select * from my_table where catsearch(text, 'blah', 'group_id = 43') > 0

这可能是最快的方法。对与您的A和B场景类似的120MB随机文本使用以上查询,只需要18个一致的获取即可。但不利的一面是,创建CTXCAT索引花费了将近11分钟并占用了1.8GB的空间。

(注意:Oracle
Text在这里似乎可以正常工作,但是我对Text不熟悉,我不能保证这不是对@NullUserException之类的这些索引的不当使用。)

多列索引与索引联接

对于您在编辑中描述的情况, 通常
在(A,B)上使用索引与在A和B上连接单独的索引之间不会有显着差异。我使用与您所描述的数据和索引相似的数据构建了一些测试对于多列索引,join只需要7个一致的获取,而2个一致的获取。

这样做的原因是因为Oracle检索块中的数据。一个块通常为8K,并且已经对索引块进行了排序,因此您可以在几个块中容纳500到2000个值。如果您担心性能,通常只需要读取和写入块的IO即可。Oracle是否必须将几千行连接在一起是不重要的CPU时间。

但是,这不适用于Oracle Text索引。您可以将CONTEXT索引与btree索引(“ bitmap and”?)连接起来,但是性能很差。



 类似资料:
  • 回顾 在前面的章节(分页),我们已经加强了数据库查询,因此能够在页面上获取各种查询。 今天,我们会继续探讨数据库的话题,只是领域不同。所有存储内容的应用程序必须提供搜索能力。 许多其它类型的网站可能使用了谷歌、必应等索引所有的内容并且提供查询结果。这个对于大多数静态页面的网站,像论坛,是很好用。我们应用程序 microblog 的基本单元是用户短小的 blog,不是整个页面。我们希望搜索结果是动态

  • 问题内容: 我尝试在elasticsearchJava API上使用正则表达式运行全文搜索。我的过滤器是这样的: 但是它只与一个单词匹配,而没有短语匹配。我的意思是,例如: 如果soruce中有一个字符串,例如:“ ”,而当我的文本字符串如下:“ ”,“ ”,“ ” …时,它就起作用了。 但是,当我的realTimeTextIn字符串为“ ”时,全文搜索将不起作用。我搜索的单词不能超过一个。 我在

  • 我尝试在弹性搜索java api上使用正则表达式运行全文搜索。我的过滤器是这样的: 但是它只与一个单词匹配,而不是与短语匹配。我的意思是,例如: 如果soruce中有一个字符串,如:“

  • 问题内容: 我有以下方式的数据: 我想要正数量的总和(数量> 0)和负数量的总和(数量<0)。 如何根据条件获取这些列的总和? 问题答案: 您可以使用: LiveDemo

  • 我是从JSON文件而不是数据库获取数据。我试图根据JSON中的状态值为图标赋色,例如[if green?class1:class2]下面是我的代码。 我的HTML文件 下面是我的JSON文件。 这是我的CSS **我无法更改状态图标的颜色。我得到了这个错误** 错误类型错误:无法读取未定义的属性“status”

  • 假设我有一个存储加密文本的服务器(端到端:服务器永远看不到纯文本)。 我希望能够对该文本进行全文搜索。 我知道这很棘手,但我的想法是使用传统的全文设计(“列表”和“匹配”表,其中存储单词并与内容表中的id匹配)。当用户提交加密文本时,他们还会发送单词和各自匹配的加盐MD5。使用的盐对于每个用户都是唯一的,并且从他们的密码中恢复。 (简而言之:唯一的区别是“列表”表将包含哈希单词) 现在,这个系统会