[原]使用函数索引优化查询一例

本文介绍了一种通过创建函数索引来优化SQL查询的方法,显著降低了数据库查询中的consistentgets数量,提高了系统的整体性能。

整个过程基本上没有什么什么新意,仅为留一下一个脚印。

在一个非常空闲的系统中,用AWR发现一条语句的consistent gets比较高:

SELECT * FROM 
(
	SELECT RESOURCES.CATALOGID, ARTICLE.TITLE AS TITLE, ARTICLE.ID AS ID, 
	ARTICLE.HOTDESC AS BRIEF, ARTICLE.CREATORTIME AS TIME, ARTICLE.PIC AS PICTURE, 
	ARTICLE.ISPICARTICLE AS ISPICARTICLE, RESOURCES.URL AS FILEURL, ARTICLE.TYPE AS TYPE, 
	ARTICLE.LINKURL AS LINKURL, RESOURCES.SITE, RESOURCES.ORDERLINE AS L_ORDERS, 
	TO_CHAR(ARTICLE.CREATORTIME, 'YYYY') AS YEAR, TO_CHAR(ARTICLE.CREATORTIME, 'MM') AS MONTH, 
	TO_CHAR(ARTICLE.CREATORTIME, 'DD') AS DAY, TO_CHAR(ARTICLE.CREATORTIME, 'HH24') AS HOUR, 
	TO_CHAR(ARTICLE.CREATORTIME, 'MI') AS MINUTE, TO_CHAR(ARTICLE.CREATORTIME, 'SS') AS SECOND, 
	ARTICLE.ISNEW, ARTICLE.ISHOT, ARTICLE.TITLEFONTCOLOR, ARTICLE.TITLEFONTNAME, 
	ARTICLE.TITLEBOLD , ARTICLE.ORDERS, ARTICLE.ISINSTANCY 
	FROM ARTICLE, RESOURCES 
	WHERE 1=1 
	AND RESOURCES.STATE=1 
	AND TO_CHAR(ARTICLE.ID)=TRIM(RESOURCES.SOURCEID) 
	AND RESOURCES.CATALOGID=20794 
	ORDER BY ISINSTANCY DESC, L_ORDERS DESC
) WHERE ROWNUM<31

执行计划及统计信息如下:

--------------------------------------------------------------------------------------
| Id  | Operation                       | Name          | Rows  | Bytes | Cost (%CPU)|
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |               |    30 | 38790 |  2972   (1)|
|   1 |  COUNT STOPKEY                  |               |       |       |            |
|   2 |   VIEW                          |               |   126 |   159K|  2972   (1)|
|   3 |    SORT ORDER BY STOPKEY        |               |   126 | 18018 |  2972   (1)|
|   4 |     HASH JOIN                   |               |   126 | 18018 |  2972   (1)|
|   5 |      TABLE ACCESS BY INDEX ROWID| RESOURCES     |   126 |  7560 |    48   (0)|
|   6 |       INDEX RANGE SCAN          | IDX_RESOURCES |   126 |       |     1   (0)|
|   7 |      TABLE ACCESS FULL          | ARTICLE       | 60606 |  4912K|  2923   (1)|
--------------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
      13175  consistent gets
          0  physical reads
          0  redo size
       2654  bytes sent via SQL*Net to client
        469  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          6  rows processed

在内存查询where子句中的 RESOURCES.CATALOGID=20794 ,估计就是引起对 IDX_RESOURCES  的 RANGE SCAN ,而HASH JOIN 应该是由于 TO_CHAR(ARTICLE.ID)=TRIM(RESOURCES.SOURCEID) 这个条件引起的,由于ARTICLE.ID被TO_CHAR函数包裹着,所以,一般的索引是不会被使用的:

select 
  i.index_name,i.index_type,c.column_name 
from user_indexes i,user_ind_columns c 
where i.table_name='ARTICLE' 
  and i.index_name=c.index_name 
order by i.index_name

INDEX_NAME                     INDEX_TYPE                  COLUMN_NAME
------------------------------ --------------------------- ------------------------------
PK_ARTICLE                     NORMAL                      ID

于是乎给ARTICLE.ID建一个TO_CHAR的函数索引:

create index fidx__to_char_ARTICLE_ID on ARTICLE(TO_CHAR(id));

执行计划改变了:

-------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name                     | Rows  | Bytes | Cost (%CPU)|
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |                          |    30 | 38790 |  1561   (1)|
|   1 |  COUNT STOPKEY                  |                          |       |       |            |
|   2 |   VIEW                          |                          | 76140 |    93M|  1561   (1)|
|   3 |    SORT ORDER BY STOPKEY        |                          | 76140 |    10M|  1561   (1)|
|   4 |     NESTED LOOPS                |                          | 76140 |    10M|  1561   (1)|
|   5 |      TABLE ACCESS BY INDEX ROWID| RESOURCES                |   126 |  7560 |    48   (0)|
|   6 |       INDEX RANGE SCAN          | IDX_RESOURCES            |   126 |       |     1   (0)|
|   7 |      TABLE ACCESS BY INDEX ROWID| ARTICLE                  |   606 | 50298 |    12   (0)|
|   8 |       INDEX RANGE SCAN          | FIDX__TO_CHAR_ARTICLE_ID |    12 |       |     1   (0)|
-------------------------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         21  consistent gets
          0  physical reads
          0  redo size
       2654  bytes sent via SQL*Net to client
        469  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          6  rows processed

大大减少了 consistent gets ,这系统变得更加空闲了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值