索引未在oracle查询中使用,其中collection在where where中

时间:2017-07-25 11:30:25

标签: oracle performance indexing collections plsql

我有一个名为 MyTable 的事件表,在此表中我有MyTableId列,我们在其上创建了索引。该表有7000万行。  现在,我创建了一个清除过程,它根据表类型集合 MyTableCollection 清除事件。该集合有100行限制。因此,作为一个整体,我们可以一次清除100行。但是当我在proc中运行下面的查询时,它被卡住了40分钟。

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

当我使用硬编码值在此查询上运行分析器时,它显示了索引范围扫描

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

在幕后查询中的集合是否扮演了在查询中不使用索引的角色?我在想oracle可能会对集合中提取的行数感到困惑。我对么 ?溶液

P.S:我正在考虑实施FORALL来删除行。

1 个答案:

答案 0 :(得分:1)

执行此操作时......

WHERE   MyTableId IN (10,20,30)

...优化器足够聪明,知道它会打三行。但如果你这样做......

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

然后它不知道集合中有多少行。因此它假定有8192行,并相应地选择执行计划。

但是你可以使用cardinality提示告诉优化器集合中有多少行:

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

“此表有7000万行”

顺便说一下,检查表统计信息的新鲜度是值得的,因为我们仍然希望优化器考虑索引来获得8192/70000000行。