【发布时间】:2011-03-17 14:52:20
【问题描述】:
现在,当我在 LIKE 运算符的右侧使用 DETERMINISTIC 函数时,我遇到了一个非常棘手的问题,即 Oracle 执行计划运行严重。这是我的情况:
情况
我认为执行这样的查询是明智的(简化):
SELECT [...]
FROM customers cust
JOIN addresses addr ON addr.cust_id = cust.id
WHERE special_char_filter(cust.surname) like special_char_filter(?)
我会将? 绑定到'Eder%' 之类的东西。现在customers 和addresses 是非常大的表。这就是为什么使用索引很重要的原因。当然,addresses.cust_id 上有一个常规索引。但我还在special_char_filter(customers.surname) 上创建了一个基于函数的索引,效果非常好。
麻烦
问题是,上述涉及like 子句的查询在addresses 上创建了带有FULL TABLE SCANS 的执行计划。此查询中的某些内容似乎使 Oracle 无法使用 addresses.cust_id 上的索引。
解决方法
我发现,我的问题的解决方案是这样的:
SELECT [...]
FROM customers cust
JOIN addresses addr ON addr.cust_id = cust.id
WHERE special_char_filter(cust.surname) like ?
我从 like 运算符的右侧删除了 (DETERMINISTIC !) 函数,并在 Java 中预先计算了绑定变量。现在这个查询是超快的,没有任何 FULL TABLE SCANS。这也非常快(虽然不等价):
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 中观察到了这一点
【问题讨论】:
-
oracle 版本对于这类问题非常重要。 Oracle rdbms 版本是什么?
-
我在 11.2.0.1.0 版本中已经仔细观察过这个问题。认为它很可能也出现在 10g 版本中。不过,我无法正式确认这一点
标签: oracle sql-execution-plan sql-like deterministic