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 子查询优化思路的主要内容,如果未能解决你的问题,请参考以下文章
SQL:查询一个表的字段在另一个表里是不是存在;怎么写最优化;