现在,当我使用 Oracle 执行计划时,我遇到了一件非常棘手的事情:DETERMINISTIC
右侧的功能LIKE
操作员。这是我的情况:
情况
我认为执行这样的查询(简化的)是明智的:
SELECT [...]
FROM customers cust
JOIN addresses addr ON addr.cust_id = cust.id
WHERE special_char_filter(cust.surname) like special_char_filter(?)
我会绑定?
类似的东西'Eder%'
. Now customers
and addresses
是非常大的桌子。这就是为什么使用索引很重要。当然,还有一个常规索引addresses.cust_id
。但我还创建了一个基于函数的索引special_char_filter(customers.surname)
,效果非常好。
麻烦
问题是,上面的查询涉及到like
子句使用 FULL TABLE SCANS 创建执行计划addresses
。看起来这个查询中的某些内容阻止 Oracle 使用索引addresses.cust_id
.
解决方法
我发现,我的问题的解决方案是这样的:
SELECT [...]
FROM customers cust
JOIN addresses addr ON addr.cust_id = cust.id
WHERE special_char_filter(cust.surname) like ?
我删除了(DETERMINISTIC
!) 函数来自 like 运算符的右侧,并在 Java 中预先计算绑定变量。现在这个查询速度超快,无需任何全表扫描。这也非常快(尽管不等价):
SELECT [...]
FROM customers cust
JOIN addresses addr ON addr.cust_id = cust.id
WHERE special_char_filter(cust.surname) = special_char_filter(?)
混乱
我不明白这一点。在右侧具有确定性函数有什么问题like
操作员?我在 Oracle 11.2.0.1.0 中观察到了这一点
查询中可能什么都没有。基于成本的优化器可能会感到困惑,并认为全表扫描更快。您是否尝试过在查询中使用 HINT,强制 Oracle 使用您的索引?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)