这很慢:
select col_x from table_a where col_y in (select col_y from table_b) and fn(col_x)=0;
但我知道这将快速返回 4 行,并且我可以快速对 4 个值运行 fn()。
所以我做了一些测试,我发现这很快:
select fn(col_x) from table_a where col_y in (select col_y from table_b);
当在 where 子句中使用 fn() 时,Oracle 会在 table_a 的每一行上运行它。我怎样才能让 Oracle 首先使用 col_y 过滤器,并且只在匹配的行上运行该函数?
例如,从概念上讲,我认为这可行:
with taba as (
select fn(col_x) x from table_a where col_y in (select col_y from table_b)
)
select * from taba where x=0;
因为我认为 Oracle 会首先运行 with 子句,但 Oracle 正在“优化”这个查询并使这个运行与上面的第一个查询完全相同,其中 fn(col_x)=0 在 where 子句中。
我希望它像查询一样运行,而不是在 pl/sql block 中运行。似乎应该有办法给 oracle 一个提示,或者做一些其他的把戏,但我想不通。顺便说一句,表是在 col_y 上建立索引的,它被用作访问谓词。统计数据是最新的。
最佳答案
有两种方法可以绕过它,
1) 在子查询中添加'AND rownum >=0'以强制实现。
或
2) 在查询中使用 Case 语句来强制执行优先级(可能)
关于oracle - 如何使用 Oracle 提示或其他优化来修复函数在 where 子句中的性能问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37842994/