简体   繁体   English

在where条件中的集合中,Oracle查询中未使用索引

[英]index is not being used in oracle query with collection in where condition

I have a event table with name MyTable , in this table i have MyTableId column on which we have created index. 我有一个名为MyTable的事件表,在此表中有我们创建索引的MyTableId列。 This table is having 70 million rows. 该表有7000万行。 Now, i have created a purge proc which purges events based on a table type collection MyTableCollection . 现在,我创建了一个清除过程,该过程基于表类型集合MyTableCollection清除事件。 the collection have 100 rows limit.So, as a whole we can purge 100 rows at a time. 集合有100行的限制。因此,作为一个整体,我们可以一次清除100行。 But when I ran the below query in the proc it got stuck for 40 mins. 但是,当我在proc中运行以下查询时,它停留了40分钟。

DELETE  FROM MyTable
            WHERE   MyTableId IN (SELECT MyTableId FROM TABLE(MyTableCollection))

When i ran analyzer on this query with hard coded values, it showed indexed range scan 当我对该查询使用硬编码值运行分析器时,它显示了索引范围扫描

DELETE  FROM MyTable
                WHERE   MyTableId IN (10,20,30)

Is collection in the query behind the scenes is playing a role of not using index in the query? 后台查询中的集合是否发挥了在查询中不使用索引的作用? I am thinking oracle might get confused about the number of rows being fetched in collection. 我认为oracle可能会对在集合中获取的行数感到困惑。 Am I correct ? 我对么 ? solution? 解?

PS: I am thinking of implementing FORALL to delete the rows. PS:我正在考虑实现FORALL来删除行。

When you execute this ... 执行此操作时...

WHERE   MyTableId IN (10,20,30)

... the optimizer is clever enough to know it's going to hit three rows. ...优化器足够聪明,可以知道它将达到三行。 But if you do this ... 但是,如果您这样做...

WHERE   MyTableId IN (SELECT /*+ CARDINALITY(MyTableCollection 3) */MyTableId FROM TABLE(MyTableCollection))

Then it has no idea how many rows are in the collection. 然后,它不知道集合中有多少行。 So it assumes there are 8192 rows, and chooses the execution plan accordingly. 因此,假设有8192行,并据此选择执行计划。

But you can tell the optimizer how many rows are in the collection, by using the cardinality hint: 但是您可以通过使用cardinality提示来告诉优化器集合中有多少行:

WHERE   MyTableId IN (SELECT /*+ CARDINALITY(MyTableCollection 100) */
                      MyTableId FROM TABLE(MyTableCollection))

"This table is having 70 million rows" “此表有7000万行”

By the way, it would be worth checking the freshness of your table's statistics, because we would still expect the optimizer to consider an index to get 8192/70000000 rows. 顺便说一句,值得检查表统计信息的新鲜度,因为我们仍然希望优化器考虑将索引获得8192/70000000行的索引。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM