[英]Oracle picks wrong index when joining table
I have a long query, but similar to the short version here: 我有一个长查询,但类似于此处的短版本:
select * from table_a a
left join table_b b on
b.id = a.id and
b.name = 'CONSTANT';
There are 2 indexes on table_b
for both id
and name
, idx_id
has fewer duplicates and idx_name
has a lot of duplicates. 有2个索引
table_b
两个id
和name
, idx_id
具有较少的重复和idx_name
有很多重复的。 This is quite a large table (20M+ records). 这是一个很大的表(超过20M条记录)。 And the
join
is taking 10min+. join
需要10分钟以上。
A simple explain plan shows a lot of memory uses on the join part, and it shows it uses the index for name
as opposed to id
. 一个简单的解释计划显示了连接部分上大量的内存使用,并显示了它使用
name
索引而不是id
。
How to solve this issue? 如何解决这个问题? How to force using the
idx_id
index? 如何强制使用
idx_id
索引?
I was thinking of putting b.name='CONSTANT'
to where clause, but this is a left join and where will remove all the record that exists in table_a. 我正在考虑将
b.name='CONSTANT'
放在where子句中,但这是一个左联接,where将删除table_a中存在的所有记录。
Updated explain plan. 更新了解释计划。 Sorry cannot paste the whole plan.
抱歉,无法粘贴整个计划。
Explain plan with b.name='CONSTANT'
: 用
b.name='CONSTANT'
解释计划:
Explain plan when commenting b.name
clause: 在评论
b.name
子句时说明计划:
Add an optimizer hint to your query. 在查询中添加优化程序提示。
Without knowing your 'long' query, it's difficult to know if Oracle is using the wrong one, or if your interpretation that indexb < indexa so therefore must be quicker for query z is correct. 不知道您的“长”查询,很难知道Oracle使用的是错误的查询,还是很难理解您的解释indexb <indexa,因此对于查询z必须更快。
To add a hint the syntax is 要添加提示,语法是
select /*+ index(table_name index_name) */ * from ....;
What is the size of TABLE_A relative to TABLE_B? 相对于TABLE_B,TABLE_A的大小是多少? It wouldn't make sense to use the ID index unless TABLE_A had significantly less rows than TABLE_B.
除非TABLE_A的行数明显少于TABLE_B,否则使用ID索引是没有意义的。
Index range scans are generally only useful when they access a small percentage of the rows in a table. 索引范围扫描通常仅在访问表中一小部分行时才有用。 Oracle reads the index one-block-at-a-time, and then still has to pull the relevant row from the table.
Oracle一次读取一个索引,然后仍然必须从表中提取相关行。 If the index isn't very selective, that process can be slower than a multi-block full table scan.
如果索引不是非常有选择性,那么该过程可能比多块全表扫描要慢。
Also, it might help if you can post the full explain plan using this text format: 另外,如果您可以使用以下文本格式发布完整的说明计划,则可能会有所帮助:
explain plan for select ... ;
select * from table(dbms_xplan.display);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.