暂无图片
分享
2021-02-24
oracle 查询sum很慢

这是oracle 查询语句,查出来需要200s,返回行数100,表都不到100w,不加sum很快,加了sum很慢,sql如下:
select sum(qty) tag_qty, rc_id
from (select ser_id,
func_get_pdr_count(service_tag, dispatch_time) as qty,
rc_id
from (select s.ser_id,
p.rc_id,
s.service_tag,
s.bill_id,
s.dispatch_time
from bill_list a, ser_inf s, part_list p
where a.bill_id = s.bill_id
and p.ser_id = s.ser_id
and p.back_class <> ‘1306’
and a.service_tag <> ‘MONITOR’
and a.service_tag <> ‘N/A’
and p.ts_dsp_date > to_date(‘2021-01-30’, ‘yyyy-mm-dd’)
and p.ts_dsp_date < to_date(‘2021-02-06’, ‘yyyy-mm-dd’)
group by s.ser_id,
p.rc_id,
s.service_tag,
s.bill_id,
s.dispatch_time))
group by q.rc_id;

如下为sql执行计划:
Description Object owner Object name Cost Cardinality Bytes
SELECT STATEMENT, GOAL = ALL_ROWS 2,163 91 1,638
HASH GROUP BY 2,163 91 1,638
VIEW SYS VM_NWVW_0 2,163 91 1,638
HASH GROUP BY 2,163 91 10,010
NESTED LOOPS
NESTED LOOPS 2,162 189 20,790
NESTED LOOPS 1,972 189 17,010
TABLE ACCESS BY INDEX ROWID U_DELL PART_LIST 1,821 140 4,900
INDEX RANGE SCAN U_DELL IDX_PART_LIST_TS_DSP_DATE 22 2,803
TABLE ACCESS BY INDEX ROWID U_DELL SER_INF 2 1 55
INDEX UNIQUE SCAN U_DELL SYS_C0010144 1 1
INDEX UNIQUE SCAN U_DELL SYS_C009595 0 1
TABLE ACCESS BY INDEX ROWID U_DELL BILL_LIST 1 1 20

收藏
分享
10条回答
默认
最新
章芋文

不加sum通过first_rows会快速返回结果。
另外执行计划能够截图看看吗?

暂无图片 评论
暂无图片 有用 0

执行计划如图
image.png

暂无图片 评论
暂无图片 有用 0
你好我是李白

我看这个SQL中间那个group by,select没聚合,下面group by可不写吧,group by不写应该不影响预期结果,能少一次hash group by排序倒是。
P.RC_ID,
S.SERVICE_TAG,
S.BILL_ID,
S.DISPATCH_TIME

SELECT SUM(QTY) TAG_QTY, RC_ID
  FROM (SELECT SER_ID,
               FUNC_GET_PDR_COUNT(SERVICE_TAG, DISPATCH_TIME) AS QTY,
               RC_ID
          FROM (SELECT S.SER_ID,
                       P.RC_ID,
                       S.SERVICE_TAG,
                       S.BILL_ID,
                       S.DISPATCH_TIME
                  FROM BILL_LIST A, SER_INF S, PART_LIST P
                 WHERE A.BILL_ID = S.BILL_ID
                   AND P.SER_ID = S.SER_ID
                   AND P.BACK_CLASS <> ‘1306’
                   AND A.SERVICE_TAG <> ‘MONITOR’
                   AND A.SERVICE_TAG <> ‘N / A’
                   AND P.TS_DSP_DATE >
                       TO_DATE(‘2021 - 01 - 30’, ‘YYYY - MM - DD’)
                   AND P.TS_DSP_DATE <
                       TO_DATE(‘2021 - 02 - 06’, ‘YYYY - MM - DD’)
                 --GROUP BY S.SER_ID,
                   --       P.RC_ID,
                     --     S.SERVICE_TAG,
                       --   S.BILL_ID,
                         -- S.DISPATCH_TIME)       
                     )                         
 GROUP BY Q.RC_ID;

暂无图片 评论
暂无图片 有用 0

去掉里面group by 依然很慢需要3分50秒,结果集是118条
image.png

暂无图片 评论
暂无图片 有用 0
文成

FUNC_GET_PDR_COUNT 这个函数贴一下

或者把

FUNC_GET_PDR_COUNT(SERVICE_TAG, DISPATCH_TIME) AS QTY,

改成

1 AS QTY,

看看速度有多快?

暂无图片 评论
暂无图片 有用 0

FUNC_GET_PDR_COUNT 改成1 AS QTY,确实秒出
image.png

暂无图片 评论
暂无图片 有用 0
问题已关闭: 感谢各位大佬帮忙,问题已经得到解决
暂无图片 评论
暂无图片 有用 0
文成

看这个函数的逻辑好像是说 派单时间的最近7天是否存在这个tagid的订单,如果存在则计数
实际业务的需求是不是 最近7天有重复的tagid的订单?
最好是通过改写,去掉这个函数,因为看这个函数的结构跟查询的sql是差不多的,通过改写最内部的那个sql查询找到最近7天重复的派单,应该可以。

暂无图片 评论
暂无图片 有用 1

好的,已经让开发那边改写

暂无图片 评论
暂无图片 有用 0
问题已关闭: 问题已经得到解决
暂无图片 评论
暂无图片 有用 0
回答交流
提交
问题信息
请登录之后查看
邀请回答
暂无人订阅该标签,敬请期待~~
暂无图片墨值悬赏