Oracle10g 为什么只有在使用where子句查询子查询时,Oracle 10g SQL才会运行缓慢? 由于各种原因,我不能粘贴整个SQL,所以请考虑这个例子: select * from (select nvl(get_quantity(1), 10) available_qty from dual) where available_qty > 30;

Oracle10g 为什么只有在使用where子句查询子查询时,Oracle 10g SQL才会运行缓慢? 由于各种原因,我不能粘贴整个SQL,所以请考虑这个例子: select * from (select nvl(get_quantity(1), 10) available_qty from dual) where available_qty > 30;,oracle10g,subquery,Oracle10g,Subquery,get_quantity是一个函数,它根据通过它的记录的ID进行计算。如果它返回null,我使用nvl强制它为10 当我在父查询中使用WHERE子句时,查询运行非常慢。然而,当我注释掉WHERE子句时,它运行得非常快。我不明白的是,为什么它可以非常快地显示数据,但它不能同样快地查询数据。我也在查询子查询的结果。我的印象是子查询返回一个呈现的数据集。这几乎就像查询可用数量标识符导致它引用子查询中的某个内容一样 这就是为什么我不认为get_quantity函数的内容在这里是相关的,所以我没有麻烦发布

get_quantity是一个函数,它根据通过它的记录的ID进行计算。如果它返回null,我使用nvl强制它为10

当我在父查询中使用WHERE子句时,查询运行非常慢。然而,当我注释掉WHERE子句时,它运行得非常快。我不明白的是,为什么它可以非常快地显示数据,但它不能同样快地查询数据。我也在查询子查询的结果。我的印象是子查询返回一个呈现的数据集。这几乎就像查询可用数量标识符导致它引用子查询中的某个内容一样

这就是为什么我不认为get_quantity函数的内容在这里是相关的,所以我没有麻烦发布它。相反,我认为这是我对Oracle如何处理子查询之类的误解

你们当中有谁知道我做错了什么吗


事后思考:当我为这个问题输入标记时,出现了标记相关子查询。在进行一些快速研究时,这种类型的子查询似乎在某种程度上依赖于外部查询。这可能与我的问题有关吗?

让我们做个实验。首先,我们将运行以下查询:

select lvl, rnd 
from (select level as lvl from dual connect by level <= 5) a,
     (select dbms_random.value() rnd from dual) b;
显然,该函数是为每个连接行运行的,而不是为连接之前的子查询运行的。这是由于Oracle的优化器确定查询的最佳路径是按该顺序进行操作。为了防止这种情况,我们必须在第二个子查询中添加一些内容,使Oracle在执行联接之前完整地运行子查询。我们将把rownum添加到子查询中,因为Oracle知道,如果rownum在联接之后运行,它将发生变化。以下查询演示了这一点:

select lvl, rnd from (
select level as lvl from dual connect by level <= 5) a,
(select dbms_random.value() rnd, rownum from dual) b;

在您的例子中,where子句提供的过滤器似乎使优化器选择了一条不同的路径,在该路径中它重复运行函数,而不是一次。通过让Oracle按编写的方式运行子查询,您应该可以获得更一致的运行时间。

您是否省略了一些内部查询?——没有,只是用双表修复了它。这个查询实际上不起作用。我只是用一个简单的例子来说明一个概念。我仍然认为你在这个问题上遗漏了太多,无法得到一个好的答案——不过,我怀疑你事后的想法是正确的。where子句可能在子查询上设置了一个条件,导致它对主查询的每一行重新求值,而不是只求值一次。好吧,那么我想我真正的问题是:如何创建一个子查询来生成外部查询可以使用的完整数据集?太棒了。我只是将rownum添加到子查询的select语句中,整个运行时间从6.069秒增加到了0.171秒。你应该得到疯狂的互联网积分!
select lvl, rnd from (
select level as lvl from dual connect by level <= 5) a,
(select dbms_random.value() rnd, rownum from dual) b;
       LVL        RND
---------- ----------
         1 .028513902
         2 .028513902
         3 .028513902
         4 .028513902
         5 .028513902

5 rows selected.