1. 背景
对查询进行优化,大家首先想到的就是在 where 及 order by 涉及的列上建立索引。建了索引,如果充分利用了,效率的提升会更加明显。本文讲的就是关于如何充分利用索引的一个小技术:Index Covering。
Index Covering指索引覆盖,它覆盖了查询的所有字段(select,where,order by,group by),用来提高查询的效率。这种索引只用访问index pages,不用访问data pages,节省了大量的I/O操作,从而提高查询性能。

2. 技巧详解
例如,premium_info表上建了复合索引,为该表的3个字段,premium_info(policy_no,endorse_no,term_no),下面的两个查询,哪个符合索引覆盖呢?

查询1:

select policy_no,endorse_no,term_no,department_code from premium_info where policy_no = 'XX' and endorse_no = 'XX';

查询2:

select policy_no,endorse_no,term_no from premium_info where policy_no = 'XX' and endorse_no = 'XX';

可以先来看看执行计划,查询1的执行计划:

SELECT STATEMENT, GOAL = CHOOSE
   TABLE ACCESS BY INDEX ROWID       EPCISACCT       PREMIUM_INFO
      INDEX RANGE SCAN               EPCISACCT       UK_PREM_INFO_PLY

查询2的执行计划:

SELECT STATEMENT, GOAL = CHOOSE
   INDEX RANGE SCAN               EPCISACCT       UK_PREM_INFO_PLY

从执行计划可以看出,查询1先走index scan,然后是table access,而查询2只走了index scan,显然只有查询2是应用了索引覆盖的。

是否查询的字段和条件上都建了索引,就一定会满足索引覆盖呢?如premium_info表上除了建了上述复合索引外,还在另一个字段sale_agent_code上建了索引,看看下面这个查询语句:

select policy_no, endorse_no, term_no from premium_info
where sale_agent_code='XX';

执行计划:

SELECT STATEMENT, GOAL = CHOOSE
   TABLE ACCESS BY INDEX ROWID       EPCISACCT       PREMIUM_INFO
      INDEX RANGE SCAN               EPCISACCT       IDX_PRE_SAC

执行计划先走了sale_agent_code的索引,然后走了table access,并没有应用索引覆盖。所以索引覆盖必须满足:查询的字段和条件在同一个索引中。

Trackback

no comment untill now

Add your comment now

切换到手机版