【发布时间】:2011-11-13 13:28:27
【问题描述】:
我创建了一个如下所示的 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_ids。
理想情况下,我宁愿只搜索带有group_id = 43 的项目,所以我想要这样的索引:
create index my_idx on my_table (group_id, text) indextype is ctxsys.context;
有点像普通索引,因此可以为每个 group_id 进行单独的文本搜索。
有没有办法在 Oracle 中做这样的事情(如果这很重要,我正在使用 10g)?
编辑(澄清)
考虑一个包含一百万行和以下两列的表,A 和 B,均为数字。假设A 有 500 个不同的值,B 有 2000 个不同的值,并且每一行都是唯一的。
现在让我们考虑select ... where A = x and B = y
据我所知,A 和 B 上的索引分别对 B 进行索引搜索,这将返回 500 个不同的行,然后对这些行进行连接/扫描。在任何情况下,至少要查看 500 行(除了数据库很幸运并尽早找到所需的行。
虽然(A,B) 上的索引更有效,但它会在一次索引搜索中找到一行。
在group_id 上放置单独的索引,而我觉得文本只会给查询生成器留下两个选项。
(1) 使用group_id 索引,并扫描所有结果行中的文本。
(2) 使用文本索引,并扫描所有结果行以查找group_id。
(3) 使用两个索引,并进行连接。
而我想要:
(4) 使用(group_id, "text") 索引查找特定group_id 下的文本索引,并扫描该文本索引以查找我需要的特定行。无需扫描、检查或加入,就像在 (A,B) 上使用索引时一样。
【问题讨论】:
-
我认为你不明白
contains(text, ...)的实际作用。contains()不是您用来根据某个单词的出现来过滤结果的那种函数。它实际上会计算任何给定文本与您正在使用它的列的相关性分数。 -
假设您有一行包含
text = 'hello world'。当您执行where contains(text, 'hello') > 0时,可能会或不包括此行。你确定这是你真正想要的吗? -
@NullUserException:您能否在答案中解释
contains(...)(和catsearch(...))实际上做了什么,如果他们中的任何一个进行全文搜索? (即,如果您在文本编辑器中使用“查找”,您通常会得到什么)。
标签: sql oracle indexing full-text-indexing oracle-text