Sql Oracle查询:我如何影响验证条件的顺序?

Sql Oracle查询:我如何影响验证条件的顺序?,sql,oracle,Sql,Oracle,以下Oracle SQL中的查询示例最能说明我的问题: SELECT A.id FROM A, B WHERE A.primary_key = B.foreign_key AND B.primary_key = 'specific value' AND A.some_expensive_attribute = '1' 让我们假设A不是一个表,而是一个视图,A.some\u昂贵的属性的计算是昂贵的,考虑到为一行A计算它所花费的时间 在我的特定应用程序中,视图A很大,而B中只有几行B.prima

以下Oracle SQL中的查询示例最能说明我的问题:

SELECT A.id 
FROM A, B
WHERE A.primary_key = B.foreign_key
AND B.primary_key = 'specific value'
AND A.some_expensive_attribute = '1'
让我们假设
A
不是一个表,而是一个视图,
A.some\u昂贵的属性
的计算是昂贵的,考虑到为一行
A
计算它所花费的时间

在我的特定应用程序中,视图
A
很大,而
B
中只有几行
B.primary\u key='specific value'
。因此,计算结果最多需要10分钟

但是,当我将最后一行/条件更改为以下(完全)冗余子选择时:

AND (
     SELECT some_expensive_attribute 
        FROM A as A2 
     where A2.primary_key = A.primary_key
    ) = '1'
。。。只需要不到一秒钟。我认为在
A
-行上实现冗余subselect本身会改变检查where条件的顺序

我的问题是:是否可以告诉Oracle“最后检查此条件!”

请注意,在实际应用(PDM系统)中,我不能像这样替换最后一行。因此,这种变通方法不是真正的解决方案

谢谢

您可以尝试以下提示:

SELECT /*+ ordered */ A.id 
FROM B, A -- order changed
WHERE A.primary_key = B.foreign_key
AND B.primary_key = 'specific value'
AND A.some_expensive_attribute = '1'

它不会改变where子句中条件的计算方式,但会改变连接的方式,这里B在A之前。这是值得一试的。

通常Oracle会根据成本考虑选择最佳的计划


如果计划不是optinmal,那么您应该在查询中收集基础表的统计信息。对于统计数据收集,您可以使用
dbms\u stats.gather\u table\u stats
过程。

您是否尝试过在这些条件下使用
JOIN
在A.primary\u key=B.foreign\u key和B.primary\u key='specific value'和A.some\u昂贵的属性='1'上连接B?您的统计数据是最新的,执行计划显示了什么?它像不认识到B更具选择性,和/或没有在A(或其基础表)上使用PK索引一样发出声音?我想看看执行计划。你是否确实检查了执行计划,你说的是谓词推送,如果可以的话,它会这样做。换句话说,如果它在逻辑上是等价的,并且效率更高,那么它可能首先过滤源表(甚至可能只是一个索引,甚至不是实际的表),然后连接,而不是构建整个视图结果,然后过滤。这在查询计划中很明显。尽管我看到您主要是在“post”视图上进行过滤,但使用视图而不是表的问题在于,提示(如果需要)不会在视图中传播。我在下面的评论中提到了它。当查询根据视图进行选择时,我不会依赖提示。OP提到A是一个视图而不是一个表。默认情况下,从文档
中,提示不会在复杂视图中传播。例如,如果在针对复杂视图进行选择的查询中指定一个提示,则该提示将不被接受,因为它不会被推送到视图中。
注意:如果该视图是一个表,则不会传播该提示。