我有一个很长的查询,但类似于此处的简短版本:
select * from table_a a
left join table_b b on
b.id = a.id and
b.name = 'CONSTANT';
table_b
和id
name
上有2个索引,idx_id
重复次数较少,idx_name
有很多重复项。这是一张相当大的桌子(20M +记录)。 join
需要10分钟+。
一个简单的解释计划显示了连接部分的大量内存使用,它显示它使用name
的索引而不是id
。
如何解决这个问题?如何强制使用idx_id
索引?
我在考虑将b.name='CONSTANT'
放到where子句中,但这是一个左连接,其中将删除table_a中存在的所有记录。
更新了解释计划。抱歉无法粘贴整个计划。
用b.name='CONSTANT'
解释计划:
在评论b.name
子句时解释计划:
答案 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);