【发布时间】:2014-09-11 16:50:30
【问题描述】:
有时您会为某个您认为正确的 SQL 查询的看似不合理的结果而挣扎数小时。
有时会发现它实际上是一个 Oracle 错误,并且您的 SQL 是正确的。
是否有任何捷径可以知道是否是这种情况 - 为您节省大量时间和挫败感?
【问题讨论】:
有时您会为某个您认为正确的 SQL 查询的看似不合理的结果而挣扎数小时。
有时会发现它实际上是一个 Oracle 错误,并且您的 SQL 是正确的。
是否有任何捷径可以知道是否是这种情况 - 为您节省大量时间和挫败感?
【问题讨论】:
您可以做的一件事是应用 Oracle 10g 中引入的 NO_QUERY_TRANSFORMATION 提示。
如果这产生了预期的结果,您知道您正面临 Oracle 错误,因为没有任何提示应该改变查询的实际结果。
与此同时,您可能已经解决了您的问题,只是您的执行计划可能不令人满意。
您面临的错误(我不知道它是否是已知错误)是 Oracle 优化器在转换查询以获得更好的执行计划(合并视图等)时可能无法正确解释原始查询的意图.通过使用提示,您可以指示优化器不要这样做。
这种现象最常见于涉及内联性能视图的复杂查询。
目前我没有任何代码示例来重现此问题,但我正在努力解决。
更新: 似乎这实际上是提示的含义 - 我发现了这个:
最后对于查询块,请注意视图合并或子查询取消嵌套可能会影响我们看到的结果,从而查询块可以完全“消失”。这意味着我们命名的查询块将从查询中“转换出来”,并在其位置使用系统生成的查询块名称。我们可以在上面的第一个详细解释计划中看到系统生成的查询块和别名的示例。当然,这意味着一些针对命名查询块的提示可能不会像我们预期的那样起作用,因为命名块并不真正存在。
不过,我们确实有几个选择。首先,我们可以使用详细的解释计划识别系统生成的查询块/别名名称,然后在我们的提示中使用这些标识符。 Jonathan Lewis 在这里对这种技术进行了很好的讨论。或者,Oracle 提供 NO_QUERY_TRANSFORMATION 提示以避免导致命名查询块“消失”的转换。然而,这是一种相当激进的方法,因为这意味着 Oracle 将完全按照我们编写的方式优化查询。丢失转换的成本可能远远超过我们首先需要应用到消失的查询块的提示所带来的好处。
【讨论】: