请帮帮忙,问题索引已建,但不走索引?
SQL如下:
SELECT * 
FROM CP_SMS_PHONE_NUMBER csp
WHERE csp.phone_no like '138'||'%';
目前,phone_no字段上也有索引,在A库上执行能走索引,然后需要把A库的表导出到B库,B库上再执行相同的语句就不走索引了。具体执行计划
A库中得执行计划
---------------------------------------------------------------------------------------------------| Id  | Operation                   | Name                | Rows  | Bytes | Cost (%CPU)| Time     |---------------------------------------------------------------------------------------------------|   0 | SELECT STATEMENT            |                     |     2 |   172 |
4   (0)| 00:00:01 ||   1 |  TABLE ACCESS BY INDEX ROWID| CP_SMS_PHONE_NUMBER |     2 |   172 |
4   (0)| 00:00:01 ||*  2 |   INDEX RANGE SCAN          | IDX_PHONENO         |     2 |       |
2   (0)| 00:00:01 |--------------------------------------------------------------------------------
B库中得执行计划
| Id  | Operation         | Name                | Rows  | Bytes | Cost (%CPU)| Time     |-----------------------------------------------------------------------------------------|   0 | SELECT STATEMENT  |                     |   262 | 22270 |     6   (0)| 00:00:01 ||*  1 |  TABLE ACCESS FULL| CP_SMS_PHONE_NUMBER |   262 | 22270 |     6   (0)| 00:00:01 |--------------------------------------------------------------------------------

解决方案 »

  1.   

    Oracle使用索引的机制是这样的:在数据条数比较少的情况下,很可能是不走索引的。这是由Oracle的索引原理决定的。因为使用索引查询时,首先是要读取索引块,然后通过索引块得到rowid,然后根据这个rowid定位到数据块的位置,然后从数据块中读取数据(中间还要读取slot,这里不用考虑这么细)。因此这样至少要读入两个块进Oracle的SGA。虽然你这里统计了,可以Oracle会自动优化,根据统计信息,Oracle认为全表扫描效率更好,因此就不走索引。所以说,全表扫描到底好不好,使用索引查询到底好不好是要辩证着看,建议楼主如果有兴趣,可以深入研究下索引的机制。希望说的,能帮上楼主,继续交流,呵呵呵。
      

  2.   

    分析一下B库这个表 dbms_stats.gather_table_stats(user,table_name);
      

  3.   

    achilles12345
    说的很有道理啊,我也觉得可能oracle觉得做全表扫描代价更小,但最大的问题是为什么我在A库中执行同样的语句时就能用到索引呢?另外,在B库我已经dbms_stats.gather_table_stats(user,table_name);和dbms_stats.gather_index_stats(user,index_name);了?请问谁能分析下oracle是分析什么统计信息后(比如NUM_ROW=1448),选择是否走索引的么?
      

  4.   

    如果你A库同个表索引关键字排过序,B库同个表索引关键字没排序,就算相同的数据,也有可能A库里走索引,B库里不走索引。