• 博客访问: 9965061
  • 博文数量: 2744
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-29 09:23
个人简介

暂无介绍

文章分类

全部博文(2744)

文章存档

2013年(30)

2012年(326)

2011年(365)

2010年(349)

2009年(370)

2008年(358)

2007年(352)

2006年(366)

2005年(178)

2004年(50)

分类: Linux

2006-11-28 00:00:00

一个表建立了全文索引后,会不会导致性能的下降,一直是我比较关心的问题。

上面几篇文章讨论了包含一个全文索引查询条件的情况,从这篇文章开始讨论包含多个全文索引查询条件的情况。

全文索引性能分析(一):http://yangtingkun.itpub.net/post/468/228849

全文索引性能分析(二):http://yangtingkun.itpub.net/post/468/229120

全文索引性能分析(三):http://yangtingkun.itpub.net/post/468/229272


测试环境和上面的类似:

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;

已创建31320行。

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

索引已创建。

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

会话已更改。

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

PL/SQL 过程已成功完成。

SQL> COL NAME FORMAT A30
SQL> SET AUTOT ON

下面对比包含多个全文索引查询条件的情况:

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

ID NAME CREATED TYPE STATUS
---------- ------------------------------ ---------- ------------------ -------
25861 SYSTEM SYS_C007231 2005-10-14 INDEX VALID
25860 SYSTEM SYS_C007230 2005-10-14 INDEX VALID
.
.
.
6157 SYS CDC_SYSTEM$ 2005-09-21 TABLE VALID

已选择50行。

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

统计信息
----------------------------------------------------------
556 recursive calls
0 db block gets
1175 consistent gets
0 physical reads
0 redo size
2878 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)
50 rows processed

由于是对同一个字段进行查询,可以利用CONTAINS将查询合并:

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

ID NAME CREATED TYPE STATUS
---------- ------------------------------ ---------- ------------------ -------
25860 SYSTEM SYS_C007230 2005-10-14 INDEX VALID
25859 SYSTEM SYS_C007229 2005-10-14 INDEX VALID
.
.
.
6157 SYS CDC_SYSTEM$ 2005-09-21 TABLE VALID

已选择50行。

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

统计信息
----------------------------------------------------------
36 recursive calls
0 db block gets
82 consistent gets
0 physical reads
0 redo size
2878 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)
50 rows processed

对比上面两个查询的统计信息可以发现,虽然二者是等价的,但是利用全文索引的操作显然比多次执行操作效率要高。再看下面的情况:

SQL> SELECT COUNT(*) FROM T WHERE CONTAINS(NAME, 'SYSTEM') > 0 OR CONTAINS(NAME, 'SYS') > 0;

COUNT(*)
----------
14659

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2757 Card=1 Bytes=37)
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=2757 Card=14482 Bytes=535834)
3 2 BITMAP CONVERSION (TO ROWIDS)
4 3 BITMAP OR
5 4 BITMAP CONVERSION (FROM ROWIDS)
6 5 SORT (ORDER BY)
7 6 DOMAIN INDEX OF 'IND_T_NAME' (Cost=83)
8 4 BITMAP CONVERSION (FROM ROWIDS)
9 8 SORT (ORDER BY)
10 9 DOMAIN INDEX OF 'IND_T_NAME' (Cost=2369)

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

SQL> SELECT COUNT(*) FROM T WHERE CONTAINS(NAME, 'SYSTEM OR SYS') > 0;

COUNT(*)
----------
14659

执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2607 Card=1 Bytes=37)
1 0 SORT (AGGREGATE)
2 1 DOMAIN INDEX OF 'IND_T_NAME' (Cost=2369 Card=14208 Bytes=525696)

统计信息
----------------------------------------------------------
106 recursive calls
0 db block gets
299 consistent gets
0 physical reads
0 redo size
305 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

上面两个查询也是等价的,但是这次二者的执行计划都发生了变化。但是不出意料,仍然是使用全文索引操作进行合并的查询效率更高。

全文索引本身的功能很强大,包含了很多的操作,如果可能,尽量利用全文索引本身的操作来简化SQL的全文索引查询条件。

阅读(1708) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册