即使使用索引,查询也会执行全表扫描

时间:2017-02-07 14:13:27

标签: sql oracle performance oracle11g

我有一个简单的查询,所有已加入的列已编入索引,但仍然会收到全表扫描 以下是查询

   select rsb.REP_STATUS_BRIDGE_ID
   from REP_STATUS_BRIDGE_DETAILS rsd,
        rep_status_bridge rsb
   where rsd.REP_STATUS_BRIDGE_ID = rsb.REP_STATUS_BRIDGE_ID;

列REP_STATUS_BRIDGE_ID在两个表中都被索引,以下是解释计划

Explain plan at the following link

请协助我解决此问题

正如许多人所知,这是一个永远需要加载的查询

select count(rsb.REP_STATUS_BRIDGE_ID) from 
pcfc_dba.rep_pass rp,
pcfc_dba.rep_status_bridge rsb,
pcfc_dba.REP_STATUS_BRIDGE_DETAILS rsd,
pcfc_dba.rep_status_ref rsf
where trunc(rp.APPR_ACTION_END_DATE)>=to_date('01/02/2017','dd/MM/yyyy') 
and trunc(rp.APPR_ACTION_END_DATE)<=to_date('06/02/2107','dd/MM/yyyy')
and  rp.REP_STATUS_BRIDGE_ID = rsb.REP_STATUS_BRIDGE_ID
and   rsb.REP_STATUS_BRIDGE_ID=rsd.REP_STATUS_BRIDGE_ID
and  rsf.REP_STATUS_REF_ID=rsd.REP_STATUS_REF_ID;

The explain plan

1 个答案:

答案 0 :(得分:0)

我认为主要问题是如上所述的陈旧统计数据。 如前所述,表REP_STATUS_BRIDGE_DETAILS 1.3 mil 记录。但是在计划中我们看到全表扫描期望只有 310行(我想它是行,但我看不到标题)。请你收集统计数据:

begin 
DBMS_STATS.GATHER_TABLE_STATS (
   ownname          => USER, 
   tabname          => 'REP_STATUS_BRIDGE_DETAILS', 
   cascade          => true);
end;
/

然后从all_tables视图

中检查num_rows
 select t.owner, t.table_name, t.num_rows 
  from all_tables t 
 where t.table_name in ('REP_STATUS_BRIDGE_DETAILS');

它考虑了统计数据。在收集静力学后,您应该为两个查询获得不同的计划。