我有一个在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)在决定将此提示添加到我的查询时,是否有任何我应该注意的事项?
由于
答案 0 :(得分:9)
1)当userid = 2(不使用提示时)可能导致性能不佳的原因是什么?
因为Oracle认为使用来自(userid = 1)的计划的其中一个临时结果集会非常大 - 可能不正确。
2)为什么执行计划对于一个声明与另一个声明不同(当不使用提示时)?
基于直方图的索引
3)在决定将此提示添加到查询中时,我应该注意什么?
只要返回的记录数量很少,此提示应该是失败安全的 - 与推动优化器使用特定索引不同,此方法允许Oracle在索引更改时选择不同的计划。