Oracle 子查询优化思路

Posted 大树的困惑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle 子查询优化思路相关的知识,希望对你有一定的参考价值。

Oracle 子查询优化思路

开头:

​ 在Oracle中,支持字段级别的子查询,允许在字段嵌套查询sql,但是在面对数据量大的情况下,其效率会变的极低

问题:

通过判断统计日期和最开始交易的日期之间工作日天数

需要通过这个天数的量级来选择不同的费率

一开始使用字段的子查询获取结果

SELECT col1,col2,col3
           --150 day,
           (SELECT count(1) FROM T_PDATES  where flag=0 and DAY<20220916 and DAY>=tablea.cfm_date ) as day,
           sum(col4) ,
           sum(col5)  
           FROM tablea  group by col1,col2,col3

在数据量几千的时候,速度还可以,当数据量上w的时候,速度就慢了很多

思路:

这里想要根据源表tablea的字段和另外传入的一个字段(20220916) 来确定一个时间段内的工作日天数。

原先的做法相当于对原表里的每条记录进行遍历,拿遍历的日期去(T_PDATES)进行比对count,获得对应的天数

1.优化思路是希望子查询-》关联

​ 将天数洗到日期表中T_PDATES就可以了,因为比起大数据量级别的事实表,日期表相对来说数据量稳 定且小了多个数量级

​ 所以将子查询转换为关联查询的前提可以为:子查询的那个表数量级与原表相差较大

2.如何处理数据量级别较小的表

​ 在原有的日历表中过滤出来工作日之后,将统计日期单独作为一个字段,然后给每个工作日期进行排序,获得序号

SELECT 		DAY,
            20200916 D_date,
            row_number() over(order by DAY) rn ,
            FROM T_PDATES a  where flag=0 AND DAY <=20200916 order by DAY

接下来就是做差,我要拿每个工作日期的序号和统计日期的序号进行做差,得到的差就是相差的工作日天数

--因为引用了多次,可以将其作为临时表缓存起来
with w_tmp as (
     SELECT DAY,
            20200916 D_date,
            row_number() over(order by DAY) rn ,
            FROM T_PDATES a  where flag=0 AND DAY <=20200916 order by DAY
)
SELECT A1.DAY,
	   A2.RN-A1.RN AS BET_DATE 
	   FROM w_tmp a1 cross join (SELECT DAY,rn FROM  w_tmp where D_date=DAY)

这样便获得了每个工作日对应到统计日期之间的天数了

由于日历表的数据量很小,基本在秒级别就可以完成了

这里仅提供思路

以上是关于Oracle 子查询优化思路的主要内容,如果未能解决你的问题,请参考以下文章

oracle怎么优化

SQL:查询一个表的字段在另一个表里是不是存在;怎么写最优化;

Oracle 查询优化器是不是将*** where 子句应用于子查询或视图?

[Oracle]优化一个查询包含一个最大子查询

Oracle 的优化器是不是考虑子查询的基础列?

数据库优化