Dau*_*aud 12 oracle optimization function filter
我正在写这个效果的查询:
select *
from players
where player_name like '%K%
and player_rank<10
and check_if_player_is_eligible(player_name) > 1;
Run Code Online (Sandbox Code Playgroud)
现在,函数check_if_player_is_eligible()很重,因此,我希望查询充分过滤搜索结果,然后只对过滤后的结果运行此函数.
如何确保在执行函数之前进行所有过滤,以便它运行的次数最少?
Vin*_*rat 16
这里有两种方法可以让你在评估所有其他WHERE子句之前欺骗Oracle不评估你的函数:
使用rownum
rownum在子查询中使用伪列将强制Oracle"实现"子查询.例如,请参阅这个askTom线程.
SELECT *
FROM (SELECT *
FROM players
WHERE player_name LIKE '%K%'
AND player_rank < 10
AND ROWNUM >= 1)
WHERE check_if_player_is_eligible(player_name) > 1
Run Code Online (Sandbox Code Playgroud)
这是文档参考"Unesteding of Nested Subqueries":
除了一些例外,优化器可以取消大多数子查询.这些异常包括分层子查询和包含ROWNUM伪列的子查询,集合运算符之一,嵌套聚合函数或对查询块的相关引用,该查询块不是子查询的直接外部查询块.
使用CASE
使用CASE可以强制Oracle仅在其他条件评估为TRUE时评估您的函数.不幸的是,如果你想利用其他子句来使用索引,它会涉及重复代码,如:
SELECT *
FROM players
WHERE player_name LIKE '%K%'
AND player_rank < 10
AND CASE
WHEN player_name LIKE '%K%'
AND player_rank < 10
THEN check_if_player_is_eligible(player_name)
END > 1
Run Code Online (Sandbox Code Playgroud)