【问题标题】:Query does full table scan even with indexes即使使用索引,查询也会进行全表扫描
【发布时间】:2017-06-24 19:51:44
【问题描述】:

我有一个简单的查询,所有连接的列都被索引,但我仍然收到全表扫描 以下是查询

   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

【问题讨论】:

  • 由于没有单一的ID条件,所以会从头到尾读取一张表,索引搜索另一张表。
  • 为什么加入?为什么不使用存在?此外,现在遗留的连接语法很糟糕
  • 这在我看来是一个合理的执行计划。你有性能问题吗?如果有,你能列举出来吗?
  • 您确定该列已在 DETAILS 表中建立索引吗?是否也标记为 FK 指向另一张表?您报告的内容确实很奇怪;我会首先仔细检查这些列是否真的被索引(而不是仅仅相信或“知道”它们是)。
  • 陈旧的统计数据?

标签: sql oracle performance oracle11g


【解决方案1】:

我认为主要问题是如上所述的过时统计数据。 如您之前所说,REP_STATUS_BRIDGE_DETAILS 表有 130 万 条记录。但在计划中,我们看到全表扫描预计只会得到 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');

它考虑了统计数据。收集完静态数据后,您应该为这两个查询制定不同的计划。

【讨论】:

  • 谢谢陈旧的统计数据是问题所在。谢谢大家的支持。
猜你喜欢
  • 1970-01-01
  • 2010-12-18
  • 2012-02-04
  • 2020-01-10
  • 2021-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-22
相关资源
最近更新 更多