9

我有一个在 Oracle 数据库服务器上运行的语句。该语句有大约 5 个连接,那里没有什么异常。它看起来很像下面:

SELECT field1, field2, field3, ...  
FROM table1, table2, table3, table4, table5  
WHERE table1.id = table2.id AND table2.id = table3.id AND ...  
      table5.userid = 1

问题(有趣的是)是 userid = 1 的语句需要 1 秒才能返回 590 条记录。userid = 2 的语句需要大约 30 秒才能返回 70 条记录。

我不明白为什么差异如此之大。

似乎为 userid = 1 的语句选择了不同的执行计划,而为 userid = 2 选择了不同的执行计划。

在我实施 Oracle Hint FIRST_ROW 后,性能明显提高。两个语句(对于 id 1 和 2)都在 1 秒内产生返回。

SELECT /*+ FIRST_ROWS */
       field1, field2, field3, ...  
FROM table1, table2, table3, table4, table5  
WHERE table1.id = table2.id AND table2.id = table3.id AND ...  
      table5.userid = 1

问题:

  1. 当 userid = 2(不使用提示时)时性能不佳的可能原因是什么?
  2. 为什么一个语句和另一个语句的执行计划会不同(不使用提示时)?
  3. 在决定将此提示添加到我的查询时,我应该注意什么?
4

1 回答 1

9

1)当 userid = 2(不使用提示时)时性能不佳的可能原因是什么?

因为 Oracle 认为使用来自 (userid=1) 的计划的中间结果集之一将非常大 - 可能是错误的。

2)为什么一个语句和另一个语句的执行计划会不同(当不使用提示时)?

基于直方图的索引

3) 在决定将此提示添加到我的查询时,我应该注意什么?

只要返回的记录数量很少,这个提示就应该是故障安全的——与推动优化器使用特定索引不同,这种方法允许 Oracle 在索引发生更改时选择不同的计划。

于 2012-06-11T14:09:53.680 回答