加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

oracle10g – 为什么只有在使用where子句查询子查询时,此Oracle

发布时间:2020-12-12 12:50:59 所属栏目:百科 来源:网络整理
导读:由于各种原因,我无法粘贴整个SQL,因此请考虑以下示例: select * from (select nvl(get_quantity(1),10) available_qty from dual)where available_qty 30; get_quantity是一个函数,它根据传递给它的记录的ID进行计算.如果它返回null,我使用nvl()强制它为10.
由于各种原因,我无法粘贴整个SQL,因此请考虑以下示例:

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如何处理子查询等等的误解.

你们中的任何一位甲骨文大师都知道我做错了什么吗?

事后补充:当我输入这个问题的标签时,标签“相关子查询”出现了.在进行一些快速研究时,似乎这种类型的子查询在某种程度上取决于外部查询.这可能与我的问题有关吗?

解决方法

我们来试试吧.首先,我们将运行以下查询:

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

“a”子查询将返回5行,值为1到5.“b”子查询将返回一行随机值.如果在两个表连接之前运行该函数(通过笛卡尔坐标),则将为每一行返回相同的随机值.实际结果:

LVL        RND
---------- ----------
         1 .417932089
         2 .963531718
         3 .617016889
         4 .128395638
         5 .069405568

5 rows selected.

显然,该函数是针对每个连接的行运行的,而不是针对连接之前的子查询运行的.这是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;

从结果中可以看出,在这种情况下,该函数只运行一次:

LVL        RND
---------- ----------
         1 .028513902
         2 .028513902
         3 .028513902
         4 .028513902
         5 .028513902

5 rows selected.

在你的情况下,似乎很可能由where子句提供的过滤器使优化器采用不同的路径,它重复运行函数,而不是一次.通过使Oracle以编写的方式运行子查询,您应该获得更一致的运行时间.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读