ORACLE CTXCAT索引的INDEX SET,也是CTXCAT索引特有的属性。
CTXCAT索引是CONTEXT索引的简化版,CTXCAT索引支持的PREFERENCE包括:LEXER、STOPLIST、WORDLIST和STORAGE参数。不支持其他的参数如:DATASTORE、FILTER、SECTION GROUP。虽然支持LEXER但不支持THEME查询,而且不支持FORMAT、CHARSET和LANGUAGE列,另外不支持表和索引分区。
CTXCAT索引仅仅包含了CONTEXT索引的部分内容,但是CTXCAT索引有其自身的优点。其中最突出的优点就是支持DML同步。CONTEXT索引由于结构过于复杂,且索引的数据量一般较大,因此CONTEXT索引并不是自动同步的。而CTXCAT索引是自动同步的,当发生了DML修改时,Oracle会自动同步CTXCAT索引,降低了索引的维护成本。
CTXCAT索引的另外一个优点就是这里要介绍的INDEX SET属性,这也是CTXCAT索引特有的属性。简单的说,CTXCAT可以建立一个索引集。可以把一些经常与CTXCAT查询组合使用的查询列的索引添加到索引集中。比如,如果在查询文章内容的同时,经常需要查询文章的作者、标题或创建时间等信息,则可以将这些信息列的索引添加到索引集中,Oracle可以将这些查询封装到CATSEARCH操作中,从而提高全文索引的效率。
下面看一个简单的例子:
上面的查询不仅包括了对DOCS列的全文索引查询还包括了对CREATED列的查询。Oracle采用了先将BTREE索引转化为BITMAP索引,在进行BITMAP索引的AND的方法进行了处理。而如果采用了INDEX SET的方法,则不需要如此复杂的转化:
SQL> CREATE TABLE T (ID NUMBER, TITLE VARCHAR2(256), CREATED DATE, DOCS VARCHAR2(4000));
表已创建。 SQL> INSERT INTO T VALUES (1, 'ORACLE TEXT REFERENCE', TO_DATE('200203', 'YYYYMM'), 'This manual provides reference information for Oracle Text. Use it as a reference for creating Oracle Text indexes, for issuing Oracle Text queries, for presenting documents, and for using the Oracle Text PL/SQL packages.'); 已创建 1 行。 SQL> INSERT INTO T VALUES (2, 'ORACLE TEXT APPLICATION DEVELOPER''S GUIDE', TO_DATE('200203', 'YYYYMM'), 'This guide explains how to build query applications with Oracle Text. This preface contains these topics:'); 已创建 1 行。 SQL> INSERT INTO T VALUES (3, 'ORACLE SQL REFERENCE', TO_DATE('200210', 'YYYYMM'), 'This reference contains a complete description of the Structured Query Language (SQL) used to manage information in an Oracle database. Oracle SQL is a superset of the American National Standards Institute (ANSI) and the International Standards Organization (ISO) SQL99 standard.'); 已创建 1 行。 SQL> COMMIT; 提交完成。 SQL> CREATE INDEX IND_T_DOCS ON T (DOCS) INDEXTYPE IS CTXSYS.CTXCAT; 索引已创建。 SQL> SET AUTOT ON EXP SQL> SELECT ID FROM T WHERE CATSEARCH(DOCS, 'SQL', NULL) > 0; ID ---------- 1 3 SQL> SELECT ID FROM T WHERE CATSEARCH(DOCS, 'SQL', NULL) > 0 AND CREATED = TO_DATE('200203', 'YYYYMM'); ID ---------- 1 SQL> CREATE INDEX IND_T_CREATED ON T (CREATED); 索引已创建。 SQL> SELECT ID FROM T WHERE CATSEARCH(DOCS, 'SQL', NULL) > 0 2 AND CREATED = TO_DATE('200203', 'YYYYMM'); ID ---------- 1 SQL> DROP INDEX IND_T_DOCS; 索引已丢弃。 SQL> DROP INDEX IND_T_CREATED; 索引已丢弃。
SQL> CONN CTXSYS/CTXSYS@YANGTK
已连接。
SQL> BEGIN
2 CTX_DDL.CREATE_INDEX_SET('TEST_INDEXSET');
3 CTX_DDL.ADD_INDEX('TEST_INDEXSET', 'CREATED');
4 END;
5 /
PL/SQL 过程已成功完成。
SQL> CONN YANGTK/YANGTK@YANGTK
已连接。
SQL> CREATE INDEX IND_T_DOCS ON T (DOCS) INDEXTYPE IS CTXSYS.CTXCAT
2 PARAMETERS ('INDEX SET CTXSYS.TEST_INDEXSET');
索引已创建。
SQL> SET AUTOT ON EXP
SQL> SELECT ID FROM T WHERE CATSEARCH(DOCS, 'SQL', 'CREATED = TO_DATE(''200203'', ''YYYYMM'')') > 0;
ID
----------
1
处理支持结构性查询条件外,使用INDEX SET索引集还可以支持索引列的排序操作:
SQL> SET AUTOT OFF SQL> SELECT ID FROM T WHERE CATSEARCH(DOCS, 'SQL', NULL) > 0; ID ---------- 1 3 SQL> SELECT ID FROM T WHERE CATSEARCH(DOCS, 'SQL', 'ORDER BY CREATED DESC') > 0; ID ---------- 3 1
这种将索引添加到索引集的操作也有一定的限制,比如结构性查询的操作只能包含大于、等于、小于、IN、BETWEEN AND操作。另外,加入到索引集中索引列的大小也有限制,对于VARCHAR2和CHAR类型,大小不能超过30字符,否则会报错:
SQL> SELECT ID FROM T WHERE CATSEARCH(DOCS, 'SQL', 'CREATED != TO_DATE(''200203'', ''YYYYMM'')') > 0;
SELECT ID FROM T WHERE CATSEARCH(DOCS, 'SQL', 'CREATED != TO_DATE(''200203'', ''YYYYMM'')') > 0
*
ERROR 位于第 1 行:
ORA-29902: 执行 ODCIIndexStart() 例行程序中出错
ORA-20000: Oracle Text error:
DRG-10844: 索引无法有效执行此结构化谓词
DRG-10845: 列 CREATED ! 未编制索引
SQL> DROP INDEX IND_T_DOCS;
索引已丢弃。
SQL> CONN CTXSYS/CTXSYS@YANGTK
已连接。
SQL> BEGIN
2 CTX_DDL.ADD_INDEX('TEST_INDEXSET', 'TITLE');
3 END;
4 /
PL/SQL 过程已成功完成。
SQL> CONN YANGTK/YANGTK@YANGTK
已连接。
SQL> CREATE INDEX IND_T_DOCS ON T (DOCS) INDEXTYPE IS CTXSYS.CTXCAT
2 PARAMETERS ('INDEX SET CTXSYS.TEST_INDEXSET');
CREATE INDEX IND_T_DOCS ON T (DOCS) INDEXTYPE IS CTXSYS.CTXCAT
*
ERROR 位于第 1 行:
ORA-29855: 执行 ODCIINDEXCREATE 例行程序时出错
ORA-20000: Oracle Text 错误:
DRG-12306: 列 TITLE 对于索引集列太长
ORA-06512: 在"CTXSYS.DRUE", line 157
ORA-06512: 在"CTXSYS.CATINDEXMETHODS", line 100