全文索引性能分析

.NET环境下全文索引操作实战指南 htmltable {th, td {th {pre {简介:本示例将介绍在.NET环境中,特别是结合Windows Forms应用程序,如何对包含image字段的数据进行全文索引操作。全文索引是一种允许数据库系统快速查找和定位文本中关键词或短语的技术。在SQL Server中,全文索引功能创建了全文目录结构,用于存储经过预处理的文本数据。 阅读详情

一个表建立了全文索引后,会不会导致性能的下降,一直是我比较关心的问题。这里对这个问题进行简单的讨论。

 

一个表建立了全文索引,是希望通过全文索引来提高表的查询性能,使得原本只能通过LINK ‘%’ 的查询,变得可以通过全文索引的扫描而快速得到查询结果。

使 用全文索引并不是简单的增加了一个索引那么简单。首先,全文索引导致磁盘资源的大量占用。全文索引本身就是一个利用磁盘空间换取性能的方法。而且,全文索 引的索引同步,索引定期维护,以及表本身的维护操作使得这个表的管理成本大大的增加。最重要的一点,使用全文索引并不是对应用透明的。如果要想利用全文索 引,必须修改查询语句。原有的查询语句是不可能利用全文索引的,需要改成全文索引规定的语法。

如果付出了这么大的代价,而得不到性能的提示,甚至导致性能有所下降,未免得不偿失。好在全文索引的使用,必须通过指定操作,比如CONTAINS 、CATSEARCH 和MARCH 等,这就是说,全文索引不会影响到其他的SQL 语句。

那么剩下的问题就是全文索引能否解决好它本身的问题了。首先考虑的一个问题就是,如果查询一个常用字会不会导致全文索引返回大量的记录,从而导致性能低下。这个问题可以通过添加停用词来解决。但是停用词本身也有问题,查询英文的停用词还好说,如果仅查询中文的停用词,Oracle 直接报错。这就又需要开发的配合,如异常捕获等。

如果不使用停用词的话,那么Oracle 能否保证在恰当的时候使用全文索引就是问题的关键。

还有一个问题,Oracle 一般优先考虑域索引,对于能通过其他索引快速得到结果的情况,Oracle 是否能作出正确的判断?

上面是仅包含一个全文索引的情况,如果一张表中建立了两个全文索引,那么Oracle 能否正确的选择索引吗?

还有,如果两张表进行关联,而又对两张表的两个字段都进行了全文索引的查询,那么是否会影响查询的效率。

此外,CTXCAT 索引包含一个索引集的概念,可以向索引集中添加其他字段,来提高全文索引处理复合查询的性能。不过,这种方法一是要消耗大量的磁盘空间,二是不能替代添加字段本身的索引,那么CTXCAT 索引和其他索引的配合使用与使用CTXCAT 索引集的性能差别有多大呢,这也是值得关注的地方。

这篇文章对全文索引可能存在的性能问题进行了简单的分析,下面打算通过几篇系列文章对上面的一些问题进行详细的描述。

 

首先建立测试环境:

SQL> CREATE TABLE T
2 (ID NUMBER PRIMARY KEY, NAME VARCHAR2(4000),
3 CREATED DATE, TYPE VARCHAR2(18), STATUS VARCHAR2(7));

表已创建。

SQL> INSERT INTO T
2 SELECT ROWNUM, OWNER || ' ' || OBJECT_NAME, CREATED, OBJECT_TYPE, STATUS
3 FROM DBA_OBJECTS;

已创建31313 行。

SQL> CREATE BITMAP INDEX IND_B_T_TYPE ON T(TYPE);

索引已创建。

SQL> CREATE BITMAP INDEX IND_B_T_STATUS ON T (STATUS);

索引已创建。

SQL> CREATE INDEX IND_T_CREATED ON T(CREATED);

索引已创建。

SQL> CREATE INDEX IND_T_NAME ON T (NAME) INDEXTYPE IS CTXSYS.CONTEXT;

索引已创建。

SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD';

会话已更改。

SQL> SET AUTOT ON

下面测试一下不包含全文索引查询的SQL :

SQL> SELECT * FROM T WHERE ID = 31255;

ID NAME CREATED TYPE STATUS
---------- ------------------------------ ---------- ------------------ -------
31255 TEST ARTICLES_TAB 2006-11-09 TABLE VALID

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=2040)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=2 Card=1 Bytes=2040)
2 1 INDEX (UNIQUE SCAN) OF 'SYS_C007810' (UNIQUE) (Cost=1 Card=100)

SQL> SELECT * FROM T WHERE NAME LIKE '%SELE%' AND CREATED >= TO_DATE('2006-7-1');

ID NAME CREATED TYPE STATUS
---------- ------------------------------ ---------- ------------------ -------
26405 SELE SEQ_MANUFACTURE_CODE 2006-07-04 SYNONYM VALID
25918 SELE CAT_ATC 2006-07-06 SYNONYM VALID
25920 SELE CAT_ATC_DOSEAGE 2006-07-06 SYNONYM VALID
25921 SELE CAT_ATC_DRUG 2006-07-06 SYNONYM VALID
26406 SELE SEQ_SALER_CODE 2006-07-06 SYNONYM VALID
25919 SELE CAT_ATC_CATEGORY 2006-07-06 SYNONYM VALID

已选择6 行。

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=10 Card=55 Bytes=112200)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=10 Card=55 Bytes=112200)
2 1 INDEX (RANGE SCAN) OF 'IND_T_CREATED' (NON-UNIQUE) (Cost=2 Card=198)

从测试结果上看,全文索引对其他的查询语句没有影响,其实这个结果是意料之中的,因为只有包含了指定的查询操作(如CONTAINS 、CATSEARCH 和MARCHES 等)才会用到全文索引。

下面看一下全文索引的表现:

SQL> SELECT * FROM T WHERE CONTAINS(NAME, 'OUTLN') > 0;

ID NAME CREATED TYPE STATUS
---------- ------------------------------ ---------- ------------------ -------
25894 OUTLN ORA$GRANT_SYS_SELECT 2005-09-21 PROCEDURE VALID
25893 OUTLN OL$SIGNATURE 2005-09-21 INDEX VALID
.
.
.
6788 SYS DBMS_OUTLN_LIB 2005-09-21 LIBRARY VALID

已选择15 行。

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=2047)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=2 Card=1 Bytes=2047)
2 1 DOMAIN INDEX OF 'IND_T_NAME' (Cost=0)

统计信息
----------------------------------------------------------
16 recursive calls
0 db block gets
39 consistent gets
0 physical reads
0 redo size
996 bytes sent via SQL*Net to client
364 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
15 rows processed

Oracle 在进行全文索引的查询时,会使用全文索引的。但是同时从统计信息上也可以看到,无论是第几次执行SQL ,recursive calls 这一项都不会是0 值。这是由于处理全文索引,Oracle 要在内部调用一些存储过程。因此,即使查询结果很小,也会导致较大的逻辑读。

下面看看同时包括全文索引查询和主键查询的情况:

SQL> SELECT * FROM T WHERE CONTAINS(NAME, 'SYS') > 0 AND ID = 10000;

ID NAME CREATED TYPE STATUS
---------- ------------------------------ ---------- ------------------ -------
10000 SYS V_$BACKUP_SET 2005-09-21 VIEW VALID

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=4 Card=1 Bytes=2047)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=4 Card=1 Bytes=2047)
2 1 BITMAP CONVERSION (TO ROWIDS)
3 2 BITMAP AND
4 3 BITMAP CONVERSION (FROM ROWIDS)
5 4 INDEX (RANGE SCAN) OF 'SYS_C007810' (UNIQUE) (Cost=1 Card=22054)
6 3 BITMAP CONVERSION (FROM ROWIDS)
7 6 SORT (ORDER BY)
8 7 DOMAIN INDEX OF 'IND_T_NAME' (Cost=0 Card=22054)

统计信息
----------------------------------------------------------
93 recursive calls
0 db block gets
258 consistent gets
0 physical reads
0 redo size
531 bytes sent via SQL*Net to client
364 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
1 rows processed

从测试的结果上可以看到,Oracle 更偏向使用全文索引,明明通过主键可以快速的找到记录,而Oracle 偏要将全文索引扫描结果和主键扫描结果都转化为BITMAP ,然后进行BITMAP AND 操作,最终在转化回ROWID 。

不过上面的这个执行计划也不难理解,Oracle 认为全文索引的扫描代价是0 ,而主键的扫描代价是1 ,因此才产生了如此的执行计划。

从统计信息上看,这个执行效果并不好。不过,这并不能认为是Oracle 的问题,因为目前为止,还没有对表和索引进行分析。

SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'T')

PL/SQL 过程已成功完成。

SQL> EXEC DBMS_STATS.GATHER_INDEX_STATS(USER, 'IND_T_NAME')

PL/SQL 过程已成功完成。

SQL> EXEC DBMS_STATS.GATHER_INDEX_STATS(USER, 'IND_T_CREATED')

PL/SQL 过程已成功完成。

SQL> EXEC DBMS_STATS.GATHER_INDEX_STATS(USER, 'IND_B_T_STATUS')

PL/SQL 过程已成功完成。

SQL> EXEC DBMS_STATS.GATHER_INDEX_STATS(USER, 'IND_B_T_TYPE')

PL/SQL 过程已成功完成。

对表和索引进行了分析之后,再来执行一下刚才的查询:

SQL> SELECT * FROM T WHERE CONTAINS(NAME, 'SYS') > 0 AND ID = 10000;

ID NAME CREATED TYPE STATUS
---------- ------------------------------ ---------- ------------------ -------
10000 SYS V_$BACKUP_SET 2005-09-21 VIEW VALID

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=56)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=2 Card=1 Bytes=56)
2 1 INDEX (UNIQUE SCAN) OF 'SYS_C007810' (UNIQUE) (Cost=1 Card=31313)

统计信息
----------------------------------------------------------
10 recursive calls
0 db block gets
14 consistent gets
0 physical reads
0 redo size
531 bytes sent via SQL*Net to client
364 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

Oracle 这次选择了正确的执行计划,通过主键的唯一扫描,找到了记录。同时可以发现,recursive calls 仍然不为0 。

要想得到CONTAINS(NAME, 'SYS') > 0 的结果,仅仅靠扫描表是不行的,必须通过全文索引机制才能得到答案。这里Oracle 处于代价的考虑选择了主键扫描,但是为了得到CONTAINS 操作的结果,Oracle 必须要对查询中CONTAINS 操作进行全文索引处理。这就是recursive calls 不为0 的原因。

Oracle 处理全文索引查询一般就是上面的两种情况,一种是通过全文索引的直接扫描,另一种是通过其他执行计划获得ROWID ,再去比较这个ROWID 是否满足全文索引查询的要求。

在看一个例子:

SQL> SELECT * FROM T WHERE CONTAINS(NAME, 'OUTLN') > 0 AND ID > 15;

ID NAME CREATED TYPE STATUS
---------- ------------------------------ ---------- ------------------ -------
25894 OUTLN ORA$GRANT_SYS_SELECT 2005-09-21 PROCEDURE VALID
25893 OUTLN OL$SIGNATURE 2005-09-21 INDEX VALID
25892 OUTLN OL$NODES 2005-09-21 TABLE VALID
25891 OUTLN OL$NAME 2005-09-21 INDEX VALID
25890 OUTLN OL$HNT_NUM 2005-09-21 INDEX VALID
25889 OUTLN OL$HINTS 2005-09-21 TABLE VALID
25888 OUTLN OL$ 2005-09-21 TABLE VALID
21315 PUBLIC OUTLN_PKG 2005-09-21 SYNONYM VALID
20757 PUBLIC DBMS_OUTLN_EDIT 2005-09-21 SYNONYM VALID
20756 PUBLIC DBMS_OUTLN 2005-09-21 SYNONYM VALID
9194 SYS OUTLN_PKG 2005-09-21 PACKAGE BODY VALID
9193 SYS OUTLN_PKG 2005-09-21 PACKAGE VALID
9192 SYS OUTLN_EDIT_PKG 2005-09-21 PACKAGE BODY VALID
9191 SYS OUTLN_EDIT_PKG 2005-09-21 PACKAGE VALID
6788 SYS DBMS_OUTLN_LIB 2005-09-21 LIBRARY VALID

已选择15 行。

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=7 Card=15 Bytes=840)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=7 Card=15 Bytes=840)
2 1 DOMAIN INDEX OF 'IND_T_NAME' (Cost=2)

统计信息
----------------------------------------------------------
16 recursive calls
0 db block gets
39 consistent gets
0 physical reads
0 redo size
996 bytes sent via SQL*Net to client
364 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
15 rows processed

这个例子中,如果使用主键扫描则代价太大,Oracle 在这里选择了全文索引的扫描。看来通过收集统计信息是有助于Oracle 找到正确的执行计划。

 

 

测试环境仍然沿用上一篇文章介绍的。下面看一下这个查询语句:

SQL> SELECT * FROM T
2 WHERE CONTAINS(NAME, 'SYS') > 0
3 AND STATUS = 'INVALID';

ID NAME CREATED TYPE STATUS
---------- ------------------------------ ---------- ------------------ -------
5942 SYS ALL_REPPARAMETER_COLUMN 2005-09-21 VIEW INVALID
6319 SYS DBA_LOGSTDBY_LOG 2005-09-21 VIEW INVALID
.
.
.
10332 SYS _ALL_REPRESOLUTION 2005-09-21 VIEW INVALID

已选择19 行。

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=28 Card=7103 Bytes=397768)
1 0 TABLE ACCESS (FULL) OF 'T' (Cost=28 Card=7103 Bytes=397768)

统计信息
----------------------------------------------------------
57 recursive calls
0 db block gets
373 consistent gets
0 physical reads
0 redo size
1471 bytes sent via SQL*Net to client
375 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
19 rows processed

由于包含SYS 的记录太多,因此Oracle 没有选择全文索引,但是Oracle 为什么没有使用BITMAP 索引呢,这主要是由于确实列的直方图分析。

SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'T', METHOD_OPT => 'FOR ALL INDEXED COLUMNS SIZE 254')

PL/SQL 过程已成功完成。

SQL> SELECT * FROM T
2 WHERE CONTAINS(NAME, 'SYS') > 0
3 AND STATUS = 'INVALID';

ID NAME CREATED TYPE STATUS
---------- ------------------------------ ---------- ------------------ -------
5942 SYS ALL_REPPARAMETER_COLUMN 2005-09-21 VIEW INVALID
6319 SYS DBA_LOGSTDBY_LOG 2005-09-21 VIEW INVALID
.
.
.
10332 SYS _ALL_REPRESOLUTION 2005-09-21 VIEW INVALID

已选择19 行。

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=10 Card=19 Bytes=1064)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=10 Card=19 Bytes=1064)
2 1 BITMAP CONVERSION (TO ROWIDS)
3 2 BITMAP INDEX (SINGLE VALUE) OF 'IND_B_T_STATUS'

统计信息
----------------------------------------------------------
57 recursive calls
0 db block gets
117 consistent gets
0 physical reads
0 redo size
1471 bytes sent via SQL*Net to client
375 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
19 rows processed

收集了列的直方图信息,Oracle 采用了BITMAP 索引,使得查询效率提到。

下面看几个查询:

SQL> SELECT * FROM T WHERE CONTAINS(NAME, 'SYS') > 0
2 AND STATUS = 'INVALID'
3 AND TYPE = 'PROCEDURE';

ID NAME CREATED TYPE STATUS
---------- ------------------------------ ---------- ------------------ -------
6735 SYS DBMS_LOGMNR_FFVTOLOGMNRT 2005-09-21 PROCEDURE INVALID
6741 SYS DBMS_LOGMNR_OCTOLOGMNRT 2005-09-21 PROCEDURE INVALID

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=56)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=2 Card=1 Bytes=56)
2 1 BITMAP CONVERSION (TO ROWIDS)
3 2 BITMAP AND
4 3 BITMAP INDEX (SINGLE VALUE) OF 'IND_B_T_STATUS'
5 3 BITMAP INDEX (SINGLE VALUE) OF 'IND_B_T_TYPE'

统计信息
----------------------------------------------------------
29 recursive calls
0 db block gets
56 consistent gets
0 physical reads
0 redo size
611 bytes sent via SQL*Net to client
364 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
2 rows processed

SQL> SELECT * FROM T WHERE CONTAINS(NAME, 'SYS') > 0
2 AND STATUS = 'VALID'
3 AND TYPE = 'PROCEDURE';

ID NAME CREATED TYPE STATUS
---------- ------------------------------ ---------- ------------------ -------
25701 SYSTEM ORA$_SYS_REP_AUTH 2005-09-21 PROCEDURE VALID
25894 OUTLN ORA$GRANT_SYS_SELECT 2005-09-21 PROCEDURE VALID
.
.
.
10294 SYS XMLVALIDATE 2005-09-21 PROCEDURE VALID

已选择26 行。

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=13 Card=27 Bytes=1512)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=13 Card=27 Bytes=1512)
2 1 BITMAP CONVERSION (TO ROWIDS)
3 2 BITMAP INDEX (SINGLE VALUE) OF 'IND_B_T_TYPE'

统计信息
----------------------------------------------------------
60 recursive calls
0 db block gets
124 consistent gets
0 physical reads
0 redo size
1483 bytes sent via SQL*Net to client
375 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
26 rows processed

SQL> SELECT * FROM T WHERE CONTAINS(NAME, 'TEST') > 0
2 AND STATUS = 'VALID'
3 AND TYPE = 'TABLE';

ID NAME CREATED TYPE STATUS
---------- ------------------------------ ---------- ------------------ -------
29513 NDMAIN MLOG$_TEST_CAT_ORG 2005-10-15 TABLE VALID
29514 NDMAIN MLOG$_TEST_CAT_ORG2 2005-10-15 TABLE VALID
.
.
.
31309 TEST TT2 2006-08-02 TABLE VALID

已选择49 行。

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=24 Card=5 Bytes=280)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=24 Card=5 Bytes=280)
2 1 BITMAP CONVERSION (TO ROWIDS)
3 2 BITMAP AND
4 3 BITMAP INDEX (SINGLE VALUE) OF 'IND_B_T_TYPE'
5 3 BITMAP CONVERSION (FROM ROWIDS)
6 5 SORT (ORDER BY)
7 6 DOMAIN INDEX OF 'IND_T_NAME' (Cost=19)

统计信息
----------------------------------------------------------
19 recursive calls
0 db block gets
59 consistent gets
0 physical reads
0 redo size
2822 bytes sent via SQL*Net to client
397 bytes received via SQL*Net from client
5 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
49 rows processed

上面的3 个查询只有输入的值有所差别,但是Oracle 选择了3 种不同的执行计划,而且从执行效果上看,这些选择都是正确的。

SQL> SELECT COUNT(*) FROM T WHERE CONTAINS(NAME, 'TEST') > 0
2 AND STATUS = 'VALID'
3 AND TYPE = 'TABLE';

COUNT(*)
----------
49

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=24 Card=1 Bytes=53)
1 0 SORT (AGGREGATE)
2 1 BITMAP CONVERSION (COUNT)
3 2 BITMAP AND
4 3 BITMAP INDEX (SINGLE VALUE) OF 'IND_B_T_TYPE'
5 3 BITMAP INDEX (SINGLE VALUE) OF 'IND_B_T_STATUS'
6 3 BITMAP CONVERSION (FROM ROWIDS)
7 6 SORT (ORDER BY)
8 7 DOMAIN INDEX OF 'IND_T_NAME' (Cost=19)

统计信息
----------------------------------------------------------
79 recursive calls
0 db block gets
294 consistent gets
0 physical reads
0 redo size
303 bytes sent via SQL*Net to client
364 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
1 rows processed

上面没有改变查询的值,而是将‘* ’换成了‘COUNT(*) ’,那么Oracle 会尝试将域索引转化为BITMAP 索引,然后对所有的BITMAP 索引进行AND 操作,来避免表的访问。

上面是添加了直方图后,全文索引与BITMAP 索引配合使用情况。对于BTREE 索引来说,效果是类似的。

SQL> SELECT * FROM T WHERE CONTAINS(NAME, 'TEST') > 0 AND CREATED >= TO_DATE('2006-1-1');

ID NAME CREATED TYPE STATUS
---------- ------------------------------ ---------- ------------------ -------
30128 NDMAIN TEST 2006-02-23 INDEX VALID
31255 TEST ARTICLES_TAB 2006-11-09 TABLE VALID
.
.
.
31309 TEST TT2 2006-08-02 TABLE VALID

已选择56 行。

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=27 Card=1 Bytes=56)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=27 Card=1 Bytes=56)
2 1 BITMAP CONVERSION (TO ROWIDS)
3 2 BITMAP AND
4 3 BITMAP CONVERSION (FROM ROWIDS)
5 4 SORT (ORDER BY)
6 5 INDEX (RANGE SCAN) OF 'IND_T_CREATED' (NON-UNIQUE) (Cost=2)
7 3 BITMAP CONVERSION (FROM ROWIDS)
8 7 SORT (ORDER BY)
9 8 DOMAIN INDEX OF 'IND_T_NAME' (Cost=19)

统计信息
----------------------------------------------------------
19 recursive calls
0 db block gets
56 consistent gets
0 physical reads
0 redo size
2977 bytes sent via SQL*Net to client
397 bytes received via SQL*Net from client
5 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
56 rows processed

SQL> SELECT * FROM T WHERE CONTAINS(NAME, 'TEST') > 0 AND CREATED >= TO_DATE('2006-11-1');

ID NAME CREATED TYPE STATUS
---------- ------------------------------ ---------- ------------------ -------
31255 TEST ARTICLES_TAB 2006-11-09 TABLE VALID
.
.
.
31305 TEST T 2006-11-14 TABLE VALID

已选择49 行。

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=24 Card=1 Bytes=56)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=24 Card=1 Bytes=56)
2 1 INDEX (RANGE SCAN) OF 'IND_T_CREATED' (NON-UNIQUE) (Cost=2 Card=70)

统计信息
----------------------------------------------------------
59 recursive calls
0 db block gets
119 consistent gets
0 physical reads
0 redo size
2675 bytes sent via SQL*Net to client
397 bytes received via SQL*Net from client
5 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
49 rows processed

SQL> SELECT * FROM T WHERE CONTAINS(NAME, 'TEST') > 0 AND CREATED >= TO_DATE('2005-1-1');

ID NAME CREATED TYPE STATUS
---------- ------------------------------ ---------- ------------------ -------
31309 TEST TT2 2006-08-02 TABLE VALID
31308 TEST TT 2006-08-02 TABLE VALID
.
.
.
6720 SYS DBMS_JAVA_TEST 2005-09-21 PACKAGE VALID

已选择118 行。

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=44 Card=118 Bytes=6608)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=44 Card=118 Bytes=6608)
2 1 DOMAIN INDEX OF 'IND_T_NAME' (Cost=19)

统计信息
----------------------------------------------------------
19 recursive calls
0 db block gets
67 consistent gets
0 physical reads
0 redo size
6124 bytes sent via SQL*Net to client
441 bytes received via SQL*Net from client
9 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
118 rows processed

从上面的一系列测试可以发现,如果在表和索引的统计信息的基础上,添加列的直方图,将更加有助于Oracle 选择最有的执行计划。

根据测试,在大部分的情况下,只要收集了正确的统计信息,Oracle 会字段的选择合适的执行计划,全文索引导致执行计划的改变并不会降低系统的性能。

 


YOLO11改进|注意力机制篇|引入ELA注意力机制 YOLO11添加ELA注意力机制 阅读详情

相关推荐

GEE入门之路(从【初学者】角度,大白话)——附海面风速插值代码

非常初级的GEE入门教程!大白话!有手就行!附海面风速插值代码,克里金插值,时间插值。

weixin_46812066的博客 4086

Oracle 使用dbms_stats.gather_table_stats更新统计信息

查看表分析时间: select table_name,LAST_ANALYZED from dba_tables where table_name = UPPER('crm_interceptor_log') and rownum<2; 更新表统计信息: exec dbms_stats.gather_table_stats (OWNNAME=>'XXX',tabname=&amp

tmaczt的博客 3107

无人机精准降落辅助系统核心技术解析

接近地面时(<10米)切换至基于图像的视觉伺服(IBVS),依据图像特征点偏移(如靶标图案、LED标记)微调姿态,消除位置累积误差。通过SRUKF(平方根无迹卡尔曼滤波) 算法融合三类数据,输出6自由度位姿估计(精度达厘米级),抑制单一传感器噪声。权值根据信噪比动态调整。模型预测控制(MPC):针对斜坡降落,构建包含平台倾角、风扰的动力学方程,滚动求解最优油门序列。动态照明适配:针对夜间或低光照场景,系统向降落平台发送亮度调节指令,如增强红外信标强度或调整可见光LED阵列,确保特征识别鲁棒性。

YUNZHUO666的博客 1695

plsql oracle 11g 所有索引字段理解

normal https://blog.youkuaiyun.com/ciqu9915/article/details/100214294 uique bitmap https://blog.youkuaiyun.com/renfengjun/article/details/8453999 ctxsys.contex 全文索引 https://www.cnblogs.com/bingya/p/81...

liangdingguo的博客 277

YOLOv5轻量化实战:从Ghost模块到工业级部署的完整指南

本文详细介绍了YOLOv5轻量化实战,重点解析了Ghost模块在工业检测中的应用及其优化策略。通过Ghost卷积技术,模型参数量和GFLOPs显著降低,同时保持高精度,适用于实时性要求严格的工业场景。文章还提供了从模型优化到TensorRT加速的完整部署指南,助力开发者实现高效工业级应用。

weixin_28223453的博客 489

逆变器专题(3)-锁相环-PLL

锁相环作为并网逆变器的第一道门户,其锁相的精度将直接影响逆变器是否并网成功,若锁相精度较差,则会直接导致系统的功率因数下降,产生无功等等。在有关文献中指出,提高PLL带宽可以准确且快速进行锁相,而当电网电压含有谐波时,可适当降低带宽抵制谐波的干扰。成为变化量,而如果两者旋转速度达到一致时,所在的交轴分量。ki很大,即带宽很大时,稳定裕度不够,锁相环锁不住。为交流量,当频率锁定而相位没有锁定时,即。,即控制环前馈,可实现将锁相速度的加快。控为0,则可实现系统完美锁相。mod,取余,可减少存储空间。

cyc19980105的博客 6181

Oracle全文索引

转自http://www.cnblogs.com/tracy/archive/2010/10/20/1856480.html,感谢原作者! 不使用Oracle text功能,也有很多方法可以在Oracle数据库中搜索文本.可以使用标准的INSTR函数和LIKE操作符实现。 SELECT *FROM mytext WHERE INSTR (thetext, 'Oracle') > 0; SE

bnuside的专栏 841

ArcGIS新手必看:用Landsat 8数据计算植被覆盖度的完整流程(附DEM裁剪技巧)

本文为ArcGIS新手提供了使用Landsat 8数据计算植被覆盖度的完整流程指南。详细讲解了从数据预处理、NDVI计算到基于像元二分模型反演植被覆盖度的核心步骤,并重点分享了利用DEM进行精确裁剪的实用技巧,帮助用户高效完成地表信息提取与分析。

weixin_29279047的博客 238

MySQL索引

加快表的查询速度,还可以对字段排序1.加快查询速率(利用定位技术)2.提高查询速度3.降低数据库的IO成本,排序成本4.加快表与表之间的连接5.通过创建唯一性索引保证表数据的唯一性6.使用分组和排序时,可以大大减少分组和排序时间索引分为:① 普通索引 :针对所有字段,没有特殊的需求/规则② 唯一索引 : 针对唯一性的字段,仅允许出现一次空值③ 组合索引 (多列/多字段组合形式的索引)④ 全文索引(varchar char text)MySQL为了优化对文本内容搜索的一种机制。

MUDXT的博客 772

Windows安装ros2(Jazzy版本+win10/win11)-1.配置windows终端

更高版本的terminal可能设置里更加丰富, 有默认以管理员身份启动的选项等,可自行配置。打开微软应用商店, 在其中搜索并下载 Terminal 即可(注意别挂梯子)下载并安装, 安装的位置自行替换,建议别放到系统盘中。点击任务栏中的搜索, 输入store。

weixin_48398592的博客 1454

基于经验模态分解和核主成分分析结合长短期记忆网络EMD-KPCA-LSTM的光伏功率预测算法--Matlab

基于经验模态分解和核主成分分析结合长短期记忆网络EMD-KPCA-LSTM的光伏功率预测算法--Matlab

前程算法屋的博客 625

初次使用全文索引--优点、缺点、使用场景

当用like‘%%’查询的时候,普通的索引是失效的,这种场景是可以通过建立全文索引的扫描而快速得到查询结果,这是它的优点。下面来做一个实验,我的环境上有一张表,有一个字段存放的是用户地址的信息: SQL> set autotrace traceonly SQL> set timing on SQL> select DISTINCT(C.NAME) from test C where C.Us

关注系统性能调优 6224

metahuman 下载材质 脸部灰白 脸部过亮

metahuman 下载材质 脸部灰白 脸部过亮

jacke121的专栏 243

MYSQL中的普通索引,主健,唯一,全文索引和性能分析

自己查询资料做了各类总结,如下:一、MYSQL中的普通索引,主健,唯一,全文索引区别PRIMARY 主键。 就是 唯一 且 不能为空。INDEX 索引,普通的UNIQUE 唯一索引。 不允许有重复。FULLTEXT 是全文索引,用于在一篇文章中,检索文本信息的。二、EXPLAIN SELECT命令EXPLAIN命令的输出结果里,第1列是从数据库读取的数据表的名字,它们按被读取的先后顺序排列。   ...

u011038738的专栏 1555

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

全文索引方面

09年马上要结束了,BLOG每天更新又坚持了一年,目前文章总数1700多篇,其中纯技术文章将近1300篇。 我比较喜欢的一句话:十年磨一剑。以前提到过,坚持10年可能会比较困难,那么至少要坚持5年,到目前为止,BLOG更新已经...

ckawt40802的专栏 99

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

ORACLE 全文检索:

全文索引: ORACLE TEXT DATASTORE PREFERENCE(一):介绍DIRECT_DATASTORE。 ORACLE TEXT DATASTORE PREFERENCE(二):介绍MULTI_COLUMN...

cuizatu9720的博客 118

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

MySQL进阶——索引简介及SQL性能分析

本文主要介绍MySQL索引内容,包括索引分类,索引语法,以及SQL的性能分析。

hujunbo553271的专栏 336

MySQL高级(二)--索引(什么是索引,分类,结构,什么时候建立,Explain使用)

MySQL高级(二)--索引(什么是索引,分类,结构,什么时候建立,Explain使用)一、索引概述二、索引的分类三、索引的结构四、建立索引的条件五、性能分析---explain 一、索引概述 1.索引就是帮助MySQL高效获取数据的数据结构。可以简单理解为排好序的快速查找数据结构。 在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据节后,就是索引。下图就是一种可能的索引方式示例: 解释下:左边是数据表,一共

weixin_44387195的博客 252

⑩② 【MySQL索引】详解MySQL`索引`:结构、分类、性能分析、设计及使用规则。

索引(index)是帮助MySQL**高效获取数据的数据结构**(有序):在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据就是索引。

ebb29bbe的博客 2298

mysql学习笔记——索引

mysql学习笔记——索引

lll2034006613的博客 174

Mysql 索引的分类

如果索引了多列(联合索引),要遵守最左前缀法则。尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间, 避免回表,提高查询效率。此时可以只将字符串的一部分前缀,建立索引,这样可以大大节约索引空间,从而提高索引效率。6.要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增 删改的效率。3.尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。...

m0_57667214的博客 364

【MySQL】-【索引的创建与设计原则】

唯一性索引与唯一性约束是一一对应关系,你给某个字段添加了唯一性约束,它会自动生成唯一性索引,你给某个字段添加了唯一性索引,他会自动具备唯一性约束。MySQL的索引包括普通索引、唯一性索引、全文索引、单列索引、多列索引和空间索引等。主键约束上自动就会有主键索引,主键索引就是聚簇索引,一张表里最多只能有一个主键索引,因为一张表中最多只能有一个主键。如果需要全文索引的是大量数据,建议先添加数据,再创建索引。一、隐式的方式创建索引。在声明有主键约束、唯一性约束、外键约束的字段上,会自动的添加相关的索引。

CaraYQ的博客 1421

MySQL索引和性能分析

MySQL索引和性能分析

pljnb的博客 449

索引-性能分析-查看SQL执行频次以及慢查询日志

索引-性能分析-SQL查询频次以及慢查询日志

LMGD的博客 923

5.2 MySql高级特性

存在则查询数据库,不存在则直接返回空。XA是数据库的分布式事务,强一致性,整个过程中,数据都处于被锁定的状态,即从prepare到commit、rollback的整个过程中,TM一直拥有参与分布式事务RM对应数据库的锁,如果有其他人要修改数据库,必修等待锁的释放。定义:通常情况下,同一张表的数据在物理层面都是放在一起的,随着表数据量过大,会带来管理上的不便,分区特性可将一张表从物理层面根据一定的规则将数据划分为多个分区,多个分区可以单独管理,甚至放在不同的磁盘/文件系统上,从而提升效率。

qq_48501521的博客 887
上一篇: 不错的关于Oracle 全文索引的文章
下一篇: [zt] Oracle 10g 统计信息自动收集功能(automatic statistics gathering)
leminsky
博客等级 码龄22年 43粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值