首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么只有当我使用where子句查询子查询时,Oracle 10g SQL才会运行缓慢?

为什么只有当我使用where子句查询子查询时,Oracle 10g SQL才会运行缓慢?
EN

Stack Overflow用户
提问于 2011-06-16 11:07:50
回答 1查看 1.5K关注 0票数 4

由于各种原因,我无法粘贴整个SQL,因此请考虑下面的示例:

代码语言:javascript
运行
AI代码解释
复制
select * 
from
    (select nvl(get_quantity(1), 10) available_qty 
     from dual)
where available_qty > 30;

get_quantity是一个函数,它根据传递给它的记录的ID进行计算。如果它返回null,则使用nvl()将其强制为10。

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

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

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

事后考虑:当我为这个问题输入标记时,出现了“关联子查询”标记。在进行一些快速研究时,这种类型的子查询似乎在一定程度上取决于外部查询。这跟我的问题有关吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-16 11:42:13

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

代码语言:javascript
运行
AI代码解释
复制
select lvl, rnd 
from (select level as lvl from dual connect by level <= 5) a,
     (select dbms_random.value() rnd from dual) b;

"a“子查询将返回值为1到5的5行,"b”子查询将返回带有随机值的一行。如果函数在连接两个表之前运行(按笛卡尔方式),则将为每一行返回相同的随机值。实际结果:

代码语言:javascript
运行
AI代码解释
复制
       LVL        RND
---------- ----------
         1 .417932089
         2 .963531718
         3 .617016889
         4 .128395638
         5 .069405568

5 rows selected.

显然,函数是为每个已连接的行运行的,而不是针对联接之前的子查询运行的。这是Oracle的优化器决定查询的最佳路径是按该顺序执行操作的结果。为了防止这种情况,我们必须在第二个子查询中添加一些内容,这将使Oracle在执行联接之前完整地运行子查询。我们将把rownum添加到子查询中,因为Oracle知道如果在连接之后运行rownum,它会改变。下面的查询说明了这一点:

代码语言:javascript
运行
AI代码解释
复制
select lvl, rnd from (
select level as lvl from dual connect by level <= 5) a,
(select dbms_random.value() rnd, rownum from dual) b;

从结果中可以看到,该函数在本例中只运行了一次:

代码语言:javascript
运行
AI代码解释
复制
       LVL        RND
---------- ----------
         1 .028513902
         2 .028513902
         3 .028513902
         4 .028513902
         5 .028513902

5 rows selected.

在您的示例中,where子句提供的筛选器可能会使优化器采用不同的路径,在那里它会重复运行函数,而不是一次。通过让Oracle按编写的方式运行子查询,您应该可以获得更一致的运行时间。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6377209

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档