使用Oracle提示"FIRST_ROWS"来提高Oracle数据库性能

bob*_*tko 8 database oracle performance hint

我有一个在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
Run Code Online (Sandbox Code Playgroud)

问题(以及有趣的)是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
Run Code Online (Sandbox Code Playgroud)

问题:
1)当userid = 2(不使用提示时),性能不佳的可能原因是什么?
2)为什么执行计划对于一个声明与另一个声明不同(当不使用提示时)?
3)在决定将此提示添加到我的查询时,是否有任何我应该注意的事项?

谢谢

sym*_*ean 9

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

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

2)为什么执行计划对于一个声明与另一个声明不同(当不使用提示时)?

基于直方图的索引

3)在决定将此提示添加到我的查询时,是否有任何我应该注意的事项?

只要返回的记录数量很少,此提示应该是失败安全的 - 与推动优化器使用特定索引不同,此方法允许Oracle在索引更改时选择不同的计划.

  • 这可能与METHOD_OPT更改其默认行为有关:http://richardfoote.wordpress.com/2008/01/04/dbms_stats-method_opt-default-behaviour-changed-in-10g-be-careful/ (2认同)