Oracle在连接表时选择了错误的索引

时间:2015-05-21 15:17:33

标签: sql oracle indexing query-performance

我有一个很长的查询,但类似于此处的简短版本:

select * from table_a a

left join table_b b on

b.id = a.id and
b.name = 'CONSTANT';

table_bid name上有2个索引,idx_id重复次数较少,idx_name有很多重复项。这是一张相当大的桌子(20M +记录)。 join需要10分钟+。

一个简单的解释计划显示了连接部分的大量内存使用,它显示它使用name的索引而不是id

如何解决这个问题?如何强制使用idx_id索引?

我在考虑将b.name='CONSTANT'放到where子句中,但这是一个左连接,其中将删除table_a中存在的所有记录。

更新了解释计划。抱歉无法粘贴整个计划。

b.name='CONSTANT'解释计划:

Wrong index

在评论b.name子句时解释计划:

enter image description here

2 个答案:

答案 0 :(得分:0)

为查询添加优化程序提示。

不知道你的长期'查询,很难知道Oracle是否使用了错误的,或者您的解释是否为indexb< indexa所以因此查询z必须更快才是正确的。

要添加提示,语法为

select /*+ index(table_name index_name) */ * from ....;

答案 1 :(得分:0)

TABLE_B相对于TABLE_B的大小是多少?除非TABLE_A的行数明显少于TABLE_B,否则使用ID索引是没有意义的。

索引范围扫描通常仅在访问表中的一小部分行时才有用。 Oracle一次读取一个块的索引,然后仍然需要从表中提取相关的行。如果索引没有选择性,那么该过程可能比多块全表扫描慢。

此外,如果您可以使用以下文本格式发布完整的解释计划,这可能会有所帮助:

explain plan for select ... ;
select * from table(dbms_xplan.display);