lob 索引 oracle,解决了困惑已久的Oracle全文索引问题

最终选用了ctxcat索引,因为建context索引的时候出现了以下错误

ERROR at line 1:

ORA-29855: error occurred in the execution of

ODCIINDEXCREATE routine

ORA-20000: Oracle Text error:

ORA-04030: out of process memory when trying to

allocate 672032 bytes (Heap for

lexic,gxlGetMem:memory)

ORA-06512: at "CTXSYS.DRUE", line 157

ORA-06512: at "CTXSYS.TEXTINDEXMETHODS", line

186

换2G内存的机器也同样问题,而且网上所有资料说的解决办法都尝试过了,没办法解决.

下午顺便测试了下ctxcat是否能用中文词法分析器,居然可以,而且没出现内存不够的错误,查询速度也非常快.

以下是建立方法

BEGIN

ctx_ddl.create_preference ('ctxcat_lexer',

'chinese_lexer');

END; create index reg_99_address_index on ucloo_reg_99(address)

indextype is ctxsys.ctxcat parameters('lexer ctxcat_lexer');

create index时间很长,必须后台运行.

ctxcat带来的额外好处是DML操作时索引也自动调整的.不像CONTEXT要定期更新索引.

以下是Oracle官方找来的资料.

开发Oracle Text(文本)的CTXCAT类型索引

作者:Douglas Scherer

了解CTXCAT类型索引并且把它与CONTEXT类型索引进行比较

在功能、易于使用和性能方面,Oracle8i 8.1.7版给Oracle

Text用户提供了先进性。它的重要组件之一是新的Oracle Text特性--CTXCAT类型索引(也称之为目录索引)。

为便于对照,让我们看一看来自以前Oracle版本的已知索引类型:CONTEXT类型索引。假设至少您已经执行了我在上篇

“探究Oracle

Text基础”(2001年3月/4月期)文章中描述的测试方案(或一些相似的方案)。这期文章中的列表3将唤起您对recipes表和数据的回忆,在那篇文章中的讨论中曾使用过它们。当在NAME列中建立CONTEXT类型的索引recipes_name_ix时,建立的对象不仅仅只有一个。表1显示了在执行如下语句后所有建立的对象:

请看Douglas Scherer发表在2001年3月/4月期刊上的文章“Exploring

Oracle Text Basics”。

CREATE INDEX recipes_name_ix

ON recipes (name)

INDEXTYPE IS CTXSYS.CONTEXT;

CONTEXT类型索引是域索引,域索引是由用户定义的。因此,CONTEXT类型索引是指由Oracle开发人员预先定义或“内置”的用户定义型索引。CONTEXT类型索引使用一个名为CONTAINS的预定义操作符。一个简单的CONTAINS搜索如下所示:

SELECT id, name

FROM recipes

WHERE CONTAINS(name, 'rice') > 0;

系统为recipes_name_ix索引在后台建立了四张名字以DR$开头的表。为了存储索引数据,表名字以$I结尾。还有一些名字以SYS开头的附加对象,这些对象在后台建立,支持唯一索引表(IOTs)和DR$表中的LOBs。最后,建立一个索引对象,其名字在CREATE

INDEX语句中被明确指定(在这个例子中,名字是recipes_name_ix)。

您不会找到任何列在域索引recipes_name_ix中或DR$RECIPES_NAME_IX$K和DR$RECIPES_NAME_IX$N的

USER_SEGMENTS数据字典视图中的片。因此,您怎么才能找出索引recipes_name_ix使用的存储总量呢?列表1中显示的查询给您提供了这个信息。为了看见另一个不同的CONTEXT类型索引所使用的空间,用那个索引的名字来代替recipes_name_ix。

与CONTEXT类型索引相对的CTXCAT类型索引

CTXCAT类型索引--在Oracle8i发行版3中所引入的--对象recipes_name_ix这样的索引来说是完美的。也就是说,CTXCAT

类型文本可以与那些存储在VARCHAR2或CLOB列中的文本片断很好地协调运行,并且不需要丰富的CONTEXT文档处理特性集(主题、部分搜索等等)。

对CTXCAT类型索引的DML改变是一种事务处理。如果会话对表recipes执行了DML操作,即使没有发布COMMIT命令,根据NAME进行的查询也能辨认出那些改变(只要它们没有被回滚)。这与CONTEXT类型索引不同,如果在相同情况下,CONTEXT索引数据必须与表数据保持周期性的同步。当使用CTXCAT类型的索引时,您不需要再关注周期性的同步。

CONTEXT类型索引的大小范围是索引信息的30%到200%。

CTXCAT类型索引的一个附加功能是它对混合查询的支持。混合查询允许其他列的查询标准与文本搜索相结合,也允许结构化分句(比如ORDER

BY)作为文本搜索本身被包括在同一索引查找中。通过索引集(包括来自索引化表的有序列集合的对象)可能进行混合查询,索引集在CREATE

INDEX语句的PARAMETERS子句中被指定。在本系列的下一篇文章中,将更详细地讨论索引集。

建立CTXCAT类型索引

尝试着建立一个基于NAME的CTXCAT类型索引。如果存在CONTEXT类型索引的话,首先删除它:

DROP INDEX recipes_name_ix;

建立CTXCAT类型索引的语句与建立CONTEXT类型索引的语句非常相似,用CTXSYS.CTXCAT简单地代替INDEXTYPE说明,如下所示:

CREATE INDEX recipes_name_ix

ON recipes (name)

INDEXTYPE IS CTXSYS.CTXCAT;

CATSEARCH查询规则

认为多个单词之间的关系是AND。

OR用垂直线表示。

前面有空格的破折号表示NOT。

双引号确定短语的界限。

使用圆括号进行分组操作。

单词前的加号(用于一些Web搜索引擎中)在CATSEARCH查询中被忽略。

这是CATSEARCH目前支持的一些操作符,不允许CONTEXT特性,例如WITHIN和FUZZY搜索。

表2显示了执行CREATE

INDEX语句后建立的对象。CREATE

INDEX语句可以使用一条PARAMETERS子句,这与建立CONTEXT类型索引时使用的CREATE

INDEX语句相似。表2中的CTXCAT列表与表1中的CONTEXT列表存在几个主要的不同之处,在表2中

建立了一个名为DR$RECIPES_NAME_IXTC的触发器。

没有建立IOT表(DR$RECIPES_NAME_IX$K和DR$RECIPES_NAME_IX$N)。

对象DR$RECIPES_NAME_IX$R是作为BTREE索引而不是表建立的。

不存在LOBs(不存在LOB片断或LOB索引)。

首先显示了一个触发器,它用来使表数据与索引集数据保持同步改变。后面的三个是非常重要的,因为它们显示了一种支持新的查询风格的结构变化。没有建立LOBs和IOTs虽然具有很大的存储优势,但是应该牢记下面的内容:

与建立在同样列上的CONTEXT类型索引相比,用CTXCAT 类型索引建立的$I表和相关索引包含更多的数据。

为CTXCAT类型索引建立的$I表的列清单依赖于您定义索引集的方式而改变。

索引集的使用将增加$I表的大小。

在本例中,没有使用索引集。

您可以使用列表2中的查询找出CTXCAT类型索引使用的空间大小。虽然您也可以使用列表1中的查询,但是列表2中的索引可以更有效地运行。但是,您不能使用列表2中的查询来查看CONTEXT类型索引的存储使用情况。

使用CTXCAT类型索引进行查询

在格式上,使用CTXCAT类型索引进行查询的基本语法与使用CONTEXT类型索引的语法相似。语法上的一处不同是CONTEXT类型索引使用

CONTAINS操作符搜索,而CTXCAT类型索引使用CATSEARCH操作符搜索。请看下面一个查询实例,它返回recipes表中那些NAME中包含单词rice的行。列表3也列出了表recipes中的名字。您认为这次查询会返回哪些行?

SELECT id, name

FROM recipes

WHERE CATSEARCH(name, 'rice', NULL) > 0;

结果,这次查询返回了recipes表中的所有行。在缺省情况下,CTXCAT类型索引使搜索对格式不敏感(CONTEXT也有相同的缺省情况)。每行都包括单词rice,虽然它两种形式出现:rice和Rice。

CATSEARCH操作符含有三个参数,顺序如下:

索引列的名字

搜索字符串

对一个或多个索引集的引用

要获得更多信息,请访问otn.oracle.com/products/intermedia/,然后点击Oracle

Text。在那里您将会发现一些代码实例、下载资料和Oracle Documentation(文档)集,在otn.oracle.com上还有一个讨论论坛。在主页上点击Discussions(讨论,在左边栏中)然后点击Enter进入Technical

Forum(技术论坛),在Technologies(技术)下寻找Oracle Text讨论论坛。

记住CONTAINS搜索的语法,它有一个可选的第三参数--积分标签(Score

Label)。因为积分基于单词在文档和文档集中出现的频率,所以它在短文本片断中没有什么意义。CATSEARCH搜索中的第三个参数引用索引集,它不能空缺。因此,如果您没有要引用的索引集,必须在第三个参数的位置置入NULL,如上述查询实例所显示的一样。

查询语言

与CONTAINS操作符相比,CATSEARCH操作符中的查询语言更少、更简单、更“类似Web”,这使应用程序开发更加简单。要了解查询语言的大概规则,请看补充文档“CATSEARCH查询规则”。

CATSEARCH搜索支持逻辑AND(并)、OR(或)和NOT(非)。

AND

当搜索字符串中的几个单词仅用空格分开时,它们之间的关系就是AND。考虑如下查询:

SELECT id, name

FROM recipes

WHERE CATSEARCH(name, 'rice bean',

NULL) > 0;

CATSEARCH操作符规定

1.分组

()

2.短语

" "

3.NOT

-

4.AND

空格

5.OR

|

通过这个查询,将返回recipe 1,因为它包括单词rice和bean。

OR

当搜索字符串中的几个单词用垂直线(|)分开时,它们之间的关系就是OR。不管垂直线前后有无空格,OR操作符将以相同的方式发挥作用。我们采用和上面相同的搜索,但是在单词rice和bean之间增加一条垂直线:

SELECT id, name

FROM recipes

WHERE CATSEARCH(name, 'rice | bean',

NULL) > 0;

该查询过程将返回全部recipe,因为它们至少都包括单词rice。

NOT

NOT由破折号(-)表示。这里还有一个查询例子,这次使用NOT操作符:

SELECT id, name

FROM recipes

WHERE CATSEARCH(name, 'rice - bean',

NULL) > 0;

该查询过程返回recipe 2和3。因为recipe 1包含单词bean,所以被排除在结果之外。

CATSEARCH不允许搜索字符串中的所有元素都使用NOT操作符的查询。因此,下面的查询将返回错误“DRG-50901:text

query parser syntax error online 1,column

1(第一行第一列存在文本查询语法分析错误)”:

SELECT id, name

FROM recipes

WHERE CATSEARCH(name, '- rice - bean',

NULL) > 0;

当NOT操作符的前后都没有空格时,NOT两边的单词被认为是一个词--就好象这两个单词被连接起来。如果运行下面的查询,将会返回哪些行呢?

SELECT id, name

FROM recipes

WHERE CATSEARCH(name, 'rice-bean',

NULL) > 0;

该查询过程将不会返回任何行,因为该查询会寻找搜索字符串ricebean。这个规则简化了使用。一个更清楚的例子是用连字符连接的单词super-hero,这个单词的意图不是“super

NOT hero”,而是一些与“superhero”同源的单词。

前面有空格而后面没有空格的NOT操作符是允许的。下面的查询将返回recipe 2和3:

SELECT id, name

FROM recipes

WHERE CATSEARCH(name, 'rice -bean',

NULL) > 0;

短语

双引号("")为短语确定界限。让我们搜索短语rice surprise:

SELECT id, name

FROM recipes

WHERE CATSEARCH(name, '"rice surprise"',

NULL) > 0;

该查询将返回recipe 2。

搜索字符串中的分组

搜索字符串中的单词和短语可以用圆括号分组。下面的查询将返回名字中包含单词rice

和tofu、或包含单词spanish的recipe:

SELECT id, name

FROM recipes

WHERE CATSEARCH(name, '(rice tofu) |

spanish', NULL) > 0;

结果集中将出现recipe 2和3。

您可以使用所有的操作符构成复杂查询。补充文档“CATSEARCH操作符优先级”显示了操作符的优先级。

结论

如果您需要根据文本片段进行文本搜索和混合查询,并且你希望是事务处理而不需要使Oracle

Text索引和表数据保持周期性同步,同时要使用CONTEXT索引类型查询操作符的子集(非CONTEXT文档处理特性),那么您应该使用CTXCAT类型索引。

表1:为Context类型索引Recipes_Name_IX建立的对象的清单

名字

类型

描述

DR$RECIPES_NAME_IX$I

存储索引数据(包括单词和事件清单)

DR$RECIPES_NAME_IX$K

IOT表

存储转变为ROWIDs和 DOCIDs的信息

DR$RECIPES_NAME_IX$N

IOT表

存储无用的DOCIDs,规划优化过程中的无用存储单元收集

DR$RECIPES_NAME_IX$R

存储为CONTAINS查询把DOCIDs转变为ROWIDs的信息

DR$RECIPES_NAME_IX$X

BTREE索引

建立在表DR$RECIPES_NAME_IX$I TOKEN_TEXT、 TOKEN_TYPE、 TOKEN_FIRST、

TOKEN_LAST、 TOKEN_COUNT列上的BTREE索引

SYS_IOT_TOP_34882

IOT索引

建立在表DR$RECIPES_NAME_IX$K TEXTKEY列上的索引

SYS_IOT_TOP_34887

IOT索引

建立在表DR$RECIPES_NAME_IX$N NLT_DOCID列上的索引

SYS_IL0000034879C00006$$

IOT索引

建立在表DR$RECIPES_NAME_IX$I TOKEN_INFO列上的索引

SYS_IL0000034884C00002$$

IOT索引

建立在表DR$RECIPES_NAME_IX$R DATA列上的索引

SYS_LOB0000034879C00006$$

LOB片段

为DR$RECIPES_NAME_IX$I.TOKEN_INFO所建立的

SYS_LOB0000034884C00002$$

LOB片段

为DR$RECIPES_NAME_IX$R.DATA 所建立的

RECIPES_NAME_IX

域索引

建立在表关于RECIPES Name列上的索引

表2:为CTXCAT类型索引Recipes_Name_IX建立的对象的清单

名称

类型

描述

DR$RECIPES_NAME_IX$I

存储索引数据(包括单词和事件清单)

DR$RECIPES_NAME_IX$R

BTREE索引

建立在表DR$RECIPES_NAME_IX$I DR$ROWID列上的BTREE索引

DR$RECIPES_NAME_IX$X

BTREE索引

建立在表DR$RECIPES_NAME_IX$I DR$TOKEN、 DR$TOKEN_TYPE、

DR$ROWID列上的BTREE索引

DR$RECIPES_NAME_IXTC

recipes触发器

调用CTXSYS控制程序,它用于使表变化和索引集数据保持同步

RECIPES_NAME_IX

域索引

建立在表recipes Name列上的域索引

Douglas Scherer (dscherer@coreparadigm.com) is president of

Core Paradigm, a management consulting firm that helps C-level

executives identify and fulfill their IT needs. He is a frequent

presenter at international conferences and author of two books on

Oracle technology. Scherer also teaches at Columbia

University.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值