OB一哥们找我优化条SQL,反馈在OceanBase存储过程执行时间很慢,需要626秒才能出结果,安排。

INSERT INTO insurance_stat_sx
(id,
stat_date,
cal_num,
underwrite_num,
veh_num,
effect_num,
effect_money,
unit_code,
life_agent_id,
life_agent_name,
sx_unit_code,
sx_unit_name,
sx_dept_group_code,
sx_dept_group_name,
sx_branch_code,
sx_branch_name,
unit_name,
dept_group_code,
dept_group_name,
dept_code,
dept_name,
section_code,
section_name,
client_type,
app_type)
SELECT t_seq_common.nextval AS id,
'2023-05-15',
cal_num,
underwrite_num,
veh_num,
effect_num,
effect_money,
unit_code,
life_agent_id,
life_agent_name,
sx_unit_code,
sx_unit_name,
sx_dept_group_code,
sx_dept_group_name,
sx_branch_code,
sx_branch_name,
unit_name,
dept_group_code,
dept_group_name,
dept_code,
dept_name,
section_code,
section_name,
client_type,
app_type
FROM (SELECT SUM(cal_num) AS cal_num,
SUM(underwrite_num) AS underwrite_num,
SUM(veh_num) AS veh_num,
SUM(effect_num) AS effect_num,
SUM(effect_money) AS effect_money,
unit_code,
life_agent_id,
life_agent_name,
sx_unit_code,
sx_unit_name,
sx_dept_group_code,
sx_dept_group_name,
sx_branch_code,
sx_branch_name,
unit_name,
dept_group_code,
dept_group_name,
dept_code,
dept_name,
section_code,
section_name,
client_type,
app_type
FROM (SELECT log.unit_code,
log.life_agent_id,
log.life_agent_name,
log.sx_unit_code,
log.sx_unit_name,
log.sx_dept_group_code,
log.sx_dept_group_name,
log.sx_branch_code,
log.sx_branch_name,
log.unit_name,
log.dept_group_code,
log.dept_group_name,
log.dept_code,
log.dept_name,
log.section_code,
log.section_name,
SUM(CASE
WHEN log.oper_type = 2 THEN
1
ELSE
0
END) cal_num,
SUM(CASE
WHEN log.oper_type = 3 THEN
1
ELSE
0
END) underwrite_num,
COUNT(DISTINCT(registration_number)) veh_num,
0 effect_num,
0 effect_money,
log.client_type,
log.app_type
FROM AAAAA log
WHERE log.life_agent_id IS NOT NULL
AND log.create_time >=
TO_DATE('2023-05-15', 'yyyy-mm-dd')
AND log.create_time <
TO_DATE('2023-05-16', 'yyyy-mm-dd')
AND log.app_type IS NOT NULL
AND log.client_type IS NOT NULL
GROUP BY log.unit_code,
log.life_agent_id,
log.life_agent_name,
log.sx_unit_code,
log.sx_unit_name,
log.sx_dept_group_code,
log.sx_dept_group_name,
log.sx_branch_code,
log.sx_branch_name,
log.unit_name,
log.dept_group_code,
log.dept_group_name,
log.dept_code,
log.dept_name,
log.section_code,
log.section_name,
log.client_type,
log.app_type
UNION ALL
SELECT log.unit_code,
log.life_agent_id,
log.life_agent_name,
log.sx_unit_code,
log.sx_unit_name,
log.sx_dept_group_code,
log.sx_dept_group_name,
log.sx_branch_code,
log.sx_branch_name,
log.unit_name,
log.dept_group_code,
log.dept_group_name,
log.dept_code,
log.dept_name,
log.section_code,
log.section_name,
0 cal_num,
0 underwrite_num,
0 veh_num,
COUNT(p.BBBB_pk) effect_num,
SUM(NVL(po.underwritten_premium, 0)) effect_money,
log.client_type,
log.app_type
FROM BBBB p,
CCCC v,
DDDD pr,
EEEE po,
(SELECT unit_code,
policy_id,
TO_CHAR(create_time, 'yyyy-mm-dd') create_time,
life_agent_id,
life_agent_name,
sx_unit_code,
sx_unit_name,
sx_dept_group_code,
sx_dept_group_name,
sx_branch_code,
sx_branch_name,
unit_name,
dept_group_code,
dept_group_name,
dept_code,
dept_name,
section_code,
section_name,
client_type,
app_type
FROM AAAAA
WHERE policy_status = '3'
AND oper_type = 7
AND life_agent_id IS NOT NULL
AND app_type IS NOT NULL
AND client_type IS NOT NULL
GROUP BY unit_code,
policy_id,
TO_CHAR(create_time, 'yyyy-mm-dd'),
life_agent_id,
life_agent_name,
sx_unit_code,
sx_unit_name,
sx_dept_group_code,
sx_dept_group_name,
sx_branch_code,
sx_branch_name,
unit_name,
dept_group_code,
dept_group_name,
dept_code,
dept_name,
section_code,
section_name,
client_type,
app_type) log
WHERE p.BBBB_pk = v.BBBB_fk
AND v.CCCC_pk = pr.CCCC_fk
AND pr.DDDD_pk = po.DDDD_fk
AND p.policy_status = '3'
AND log.policy_id = p.BBBB_pk
AND log.create_time >= '2023-05-15'
AND log.create_time < '2023-05-16'
GROUP BY log.unit_code,
log.life_agent_id,
log.life_agent_name,
log.sx_unit_code,
log.sx_unit_name,
log.sx_dept_group_code,
log.sx_dept_group_name,
log.sx_branch_code,
log.sx_branch_name,
log.unit_name,
log.dept_group_code,
log.dept_group_name,
log.dept_code,
log.dept_name,
log.section_code,
log.section_name,
log.client_type,
log.app_type)
GROUP BY unit_code,
life_agent_id,
life_agent_name,
sx_unit_code,
sx_unit_name,
sx_dept_group_code,
sx_dept_group_name,
sx_branch_code,
sx_branch_name,
unit_name,
dept_group_code,
dept_group_name,
dept_code,
dept_name,
section_code,
section_name,
client_type,
app_type) tmp;

SQL整体返回0行数据,所以insert into 也是0行,insurance_log 表 12亿行数据。

当时OB哥们给到我的时候我再忙其他事情,没有要执行计划,粗略扫了一下SQL大致的写法。

得知了 AAAAA 表 12 亿行数据以后,让他加个并行hint 试试看速度。

下面SQL除了加了并行 HINT ,后面无任何修改。

select /*+ USE_PX PARALLEL(8)*/
t_seq_common.nextval as id,
--to_char('2023-05-15', 'yyyy-mm-dd') as stat_date,
'2023-05-15',
cal_num,
underwrite_num,
veh_num,
effect_num,
effect_money,
unit_code,
life_agent_id,
life_agent_name... 省略后面SQL

并行 hint 加完以后只需要 281s 就能出结果,当时我也忙其他事情,没继续优化下去。

但是这哥们领导不依不饶,还得继续让他优化,没办法只能帮忙仔细看看了。

缓慢节点:

SELECT log.unit_code,
log.life_agent_id,
log.life_agent_name,
log.sx_unit_code,
log.sx_unit_name,
log.sx_dept_group_code,
log.sx_dept_group_name,
log.sx_branch_code,
log.sx_branch_name,
log.unit_name,
log.dept_group_code,
log.dept_group_name,
log.dept_code,
log.dept_name,
log.section_code,
log.section_name,
SUM(CASE
WHEN log.oper_type = 2 THEN
1
ELSE
0
END) cal_num,
SUM(CASE
WHEN log.oper_type = 3 THEN
1
ELSE
0
END) underwrite_num,
COUNT(DISTINCT(registration_number)) veh_num,
0 effect_num,
0 effect_money,
log.client_type,
log.app_type
FROM AAAAA log
WHERE log.life_agent_id IS NOT NULL
AND log.create_time >=
TO_DATE('2023-05-15', 'yyyy-mm-dd')
AND log.create_time <
TO_DATE('2023-05-16', 'yyyy-mm-dd')
AND log.app_type IS NOT NULL
AND log.client_type IS NOT NULL
GROUP BY log.unit_code,
log.life_agent_id,
log.life_agent_name,
log.sx_unit_code,
log.sx_unit_name,
log.sx_dept_group_code,
log.sx_dept_group_name,
log.sx_branch_code,
log.sx_branch_name,
log.unit_name,
log.dept_group_code,
log.dept_group_name,
log.dept_code,
log.dept_name,
log.section_code,
log.section_name,
log.client_type,
log.app_type
UNION ALL SELECT log.unit_code,
log.life_agent_id,
log.life_agent_name,
log.sx_unit_code,
log.sx_unit_name,
log.sx_dept_group_code,
log.sx_dept_group_name,
log.sx_branch_code,
log.sx_branch_name,
log.unit_name,
log.dept_group_code,
log.dept_group_name,
log.dept_code,
log.dept_name,
log.section_code,
log.section_name,
0 cal_num,
0 underwrite_num,
0 veh_num,
COUNT(p.BBBB_pk) effect_num,
SUM(NVL(po.underwritten_premium, 0)) effect_money,
log.client_type,
log.app_type
FROM BBBB p,
CCCC v,
DDDD pr,
EEEE po,
(SELECT unit_code,
policy_id,
TO_CHAR(create_time, 'yyyy-mm-dd') create_time,
life_agent_id,
life_agent_name,
sx_unit_code,
sx_unit_name,
sx_dept_group_code,
sx_dept_group_name,
sx_branch_code,
sx_branch_name,
unit_name,
dept_group_code,
dept_group_name,
dept_code,
dept_name,
section_code,
section_name,
client_type,
app_type
FROM AAAAA
WHERE policy_status = '3'
AND oper_type = 7
AND life_agent_id IS NOT NULL
AND app_type IS NOT NULL
AND client_type IS NOT NULL
GROUP BY unit_code,
policy_id,
TO_CHAR(create_time, 'yyyy-mm-dd'),
life_agent_id,
life_agent_name,
sx_unit_code,
sx_unit_name,
sx_dept_group_code,
sx_dept_group_name,
sx_branch_code,
sx_branch_name,
unit_name,
dept_group_code,
dept_group_name,
dept_code,
dept_name,
section_code,
section_name,
client_type,
app_type) log
WHERE p.BBBB_pk = v.BBBB_fk
AND v.CCCC_pk = pr.CCCC_fk
AND pr.DDDD_pk = po.DDDD_fk
AND p.policy_status = '3'
AND log.policy_id = p.BBBB_pk
AND log.create_time >= '2023-05-15'
AND log.create_time < '2023-05-16'
GROUP BY log.unit_code,
log.life_agent_id,
log.life_agent_name,
log.sx_unit_code,
log.sx_unit_name,
log.sx_dept_group_code,
log.sx_dept_group_name,
log.sx_branch_code,
log.sx_branch_name,
log.unit_name,
log.dept_group_code,
log.dept_group_name,
log.dept_code,
log.dept_name,
log.section_code,
log.section_name,
log.client_type,
log.app_type;

union all 上面这段SQL AAAAA 表12亿数据,返回0行。

union all 下面这段SQL BBBB p 1.9亿、CCCC v 1.9亿 、DDDD pr 2.7亿、EEEE po 4430万、log 内联视图 2025W,关联后返回0行。

这么大的数据量关联,慢也是正常,但是知道数据量以后就好办了。

 

SQL改写 + hint 干预方案 :

SELECT t_seq_common.nextval AS id,
--to_char('2023-05-15', 'yyyy-mm-dd') as stat_date,
'2023-05-15',
cal_num,
underwrite_num,
veh_num,
effect_num,
effect_money,
unit_code,
life_agent_id,
life_agent_name,
sx_unit_code,
sx_unit_name,
sx_dept_group_code,
sx_dept_group_name,
sx_branch_code,
sx_branch_name,
unit_name,
dept_group_code,
dept_group_name,
dept_code,
dept_name,
section_code,
section_name,
client_type,
app_type
FROM (SELECT SUM(cal_num) AS cal_num,
SUM(underwrite_num) AS underwrite_num,
SUM(veh_num) AS veh_num,
SUM(effect_num) AS effect_num,
SUM(effect_money) AS effect_money,
unit_code,
life_agent_id,
life_agent_name,
sx_unit_code,
sx_unit_name,
sx_dept_group_code,
sx_dept_group_name,
sx_branch_code,
sx_branch_name,
unit_name,
dept_group_code,
dept_group_name,
dept_code,
dept_name,
section_code,
section_name,
client_type,
app_type
FROM (WITH x_log AS (
                    SELECT /*+ USE_PX PARALLEL(6)*/ *
                            FROM AAAAA log
                                WHERE log.life_agent_id IS NOT NULL
AND log.app_type IS NOT NULL
AND log.client_type IS NOT NULL
AND log.create_time >= to_date('2023-05-15', 'yyyy-mm-dd')
AND log.create_time < to_date('2023-05-16', 'yyyy-mm-dd')
)
SELECT /*+ USE_PX PARALLEL(4)*/
* log.unit_code,
log.life_agent_id,
log.life_agent_name,
log.sx_unit_code,
log.sx_unit_name,
log.sx_dept_group_code,
log.sx_dept_group_name,
log.sx_branch_code,
log.sx_branch_name,
log.unit_name,
log.dept_group_code,
log.dept_group_name,
log.dept_code,
log.dept_name,
log.section_code,
log.section_name,
SUM(CASE
WHEN log.oper_type = 2 THEN
1
ELSE
0
END) cal_num,
SUM(CASE
WHEN log.oper_type = 3 THEN
1
ELSE
0
END) underwrite_num,
COUNT(DISTINCT(registration_number)) veh_num,
0 effect_num,
0 effect_money,
log.client_type,
log.app_type
FROM x_log log
GROUP BY log.unit_code,
log.life_agent_id,
log.life_agent_name,
log.sx_unit_code,
log.sx_unit_name,
log.sx_dept_group_code,
log.sx_dept_group_name,
log.sx_branch_code,
log.sx_branch_name,
log.unit_name,
log.dept_group_code,
log.dept_group_name,
log.dept_code,
log.dept_name,
log.section_code,
log.section_name,
log.client_type,
log.app_type
UNION ALL
SELECT /*+
                      MERGE(log)
                      USE_PX PARALLEL(5)
PQ_DISTRIBUTE(p hash, hash)
PQ_DISTRIBUTE(v hash, hash)
PQ_DISTRIBUTE(pr hash, hash)
PQ_DISTRIBUTE(po hash, hash)
PQ_DISTRIBUTE(log hash, hash)
*/
log.unit_code,
log.life_agent_id,
log.life_agent_name,
log.sx_unit_code,
log.sx_unit_name,
log.sx_dept_group_code,
log.sx_dept_group_name,
log.sx_branch_code,
log.sx_branch_name,
log.unit_name,
log.dept_group_code,
log.dept_group_name,
log.dept_code,
log.dept_name,
log.section_code,
log.section_name,
0 cal_num,
0 underwrite_num,
0 veh_num,
COUNT(p.BBBB_pk) effect_num,
SUM(nvl(po.underwritten_premium, 0)) effect_money,
log.client_type,
log.app_type
FROM BBBB p,
CCCC v,
DDDD pr,
EEEE po,
(SELECT /*+ USE_PX PARALLEL(5)*/
unit_code,
policy_id,
to_char(create_time, 'yyyy-mm-dd') create_time,
life_agent_id,
life_agent_name,
sx_unit_code,
sx_unit_name,
sx_dept_group_code,
sx_dept_group_name,
sx_branch_code,
sx_branch_name,
unit_name,
dept_group_code,
dept_group_name,
dept_code,
dept_name,
section_code,
section_name,
client_type,
app_type
FROM x_log log
WHERE policy_status = '3'
AND oper_type = 7
GROUP BY unit_code,
policy_id,
to_char(create_time, 'yyyy-mm-dd'),
life_agent_id,
life_agent_name,
sx_unit_code,
sx_unit_name,
sx_dept_group_code,
sx_dept_group_name,
sx_branch_code,
sx_branch_name,
unit_name,
dept_group_code,
dept_group_name,
dept_code,
dept_name,
section_code,
section_name,
client_type,
app_type) log
WHERE p.BBBB_pk = v.BBBB_fk
AND v.CCCC_pk = pr.CCCC_fk
AND pr.DDDD_pk = po.DDDD_fk
AND p.policy_status = '3'
AND log.policy_id = p.BBBB_pk
GROUP BY log.unit_code,
log.life_agent_id,
log.life_agent_name,
log.sx_unit_code,
log.sx_unit_name,
log.sx_dept_group_code,
log.sx_dept_group_name,
log.sx_branch_code,
log.sx_branch_name,
log.unit_name,
log.dept_group_code,
log.dept_group_name,
log.dept_code,
log.dept_name,
log.section_code,
log.section_name,
log.client_type,
log.app_type)
GROUP BY unit_code,
life_agent_id,
life_agent_name,
sx_unit_code,
sx_unit_name,
sx_dept_group_code,
sx_dept_group_name,
sx_branch_code,
sx_branch_name,
unit_name,
dept_group_code,
dept_group_name,
dept_code,
dept_name,
section_code,
section_name,
client_type,
app_type
) tmp;

最终上面SQL 27s 就能跑出结果。

这个案例从始至终没有看过执行计划 (OB的执行计划我也看不懂,看了也是白看)。

当具备一定优化理论知识之后,我们可以不看执行计划,直接根据 SQL 写法和表的数据量来判断是否走 NL 还是 HASH,

然后一直这样进行下去直到 SQL 语句中所有表都关联完毕,如果大家长期采用此方法进行锻炼,久而久之,你自己的脑袋就是 CBO。

oceanbase 数据库SQL优化 (把你的脑袋当成CBO)的更多相关文章

  1. 我的mysql数据库sql优化原则

    原文 我的mysql数据库sql优化原则 一.前提 这里的原则 只是针对mysql数据库,其他的数据库 某些是殊途同归,某些还是存在差异.我总结的也是mysql普遍的规则,对于某些特殊情况得特殊对待. ...

  2. 数据库sql优化方案

    声明:这个不是我自己写的,是我们老师给我,我拿出来分享一下! 为什么要优化:     随着实际项目的启动,数据库经过一段时间的运行,最初的数据库设置,会与实际数据库运行性能会有一些差异,这时我们    ...

  3. SQL优化- 数据库SQL优化——使用EXIST代替IN

    数据库SQL优化——使用EXIST代替IN 1,查询进行优化,应尽量避免全表扫描 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引 . 尝试下面的 ...

  4. 数据库sql优化总结之5--数据库SQL优化大总结

    数据库SQL优化大总结 小编最近几天一直未出新技术点,是因为小编在忙着总结整理数据库的一些优化方案,特此奉上,优化总结较多,建议分段去消化,一口吃不成pang(胖)纸 一.百万级数据库优化方案 1.对 ...

  5. 数据库SQL优化大总结之百万级数据库优化方案

    网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...

  6. (转)数据库SQL优化大总结之 百万级数据库优化方案

    网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...

  7. 数据库 SQL 优化大总结之:百万级数据库优化方案

    网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...

  8. 数据库SQL优化大总结之 百万级数据库优化方案(转载)

    网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...

  9. 数据库SQL优化大总结之百万级数据库优化方案(转)

    add by zhj: 作者没有指定是哪个数据库,这只是一个近似通用的总结.对于某个特定的数据库,有些条目可能并不适用. 原文:http://www.cnblogs.com/yunfeifei/p/3 ...

  10. 关于数据库SQL优化

    1.数据库访问优化   要正确的优化SQL,我们需要快速定位能性的瓶颈点,也就是说快速找到我们SQL主要的开销在哪里?而大多数情况性能最慢的设备会是瓶颈点,如下载时网络速度可能会是瓶颈点,本地复制文件 ...

随机推荐

  1. Java原生图片Base64转码与Base64解码

    原文地址 import org.apache.commons.codec.binary.*; import java.io.*; import java.net.*; /** * 将file文件转换为 ...

  2. OO第二次大作业

    前言 前言的前言 第二篇blog跟上一篇只隔了将近一个月,但是感觉心境上好像发生了很多的变化,认识到了自己存在的很多不足(可能是菜单折磨的),感觉对很多东西都一知半解,希望在写完这篇总结性blog之后 ...

  3. 如何新建一个django项目

    1.新建项目 2选择django 3.接下来我们进入 djangotest目录输入以下命令,启动服务器: python manage.py runserver 0.0.0.0:8000 0.0.0.0 ...

  4. Avalonia项目在OpenKylin运行踩坑

    Avalonia项目在OpenKylin运行踩坑 本篇博客记录OpenKylin开源操作系统中运行Avalonia项目遇到的各种问题,会一直更新,最新的内容请点击文末的链接跳转到我的博客原文地址查看. ...

  5. [ansible]建立ssh互信

    创建密钥 # 创建基于rsa算法的密钥,也可以创建ed25519算法的密钥,性能比rsa高 # 一般直接回车即可 ssh-keygen -t rsa 少量建立互信 如果主机数不多的话,可以手动建立互信 ...

  6. go接收alertmanager告警并发送钉钉

    前言 功能:作为 alertmanager 的 webhook receiver,提取需要的数据转发到钉钉群机器人的webhook web框架:gin alertmanager版本:0.24 系统版本 ...

  7. 春秋云镜像-CVE-2022-0788

    准备: 攻击机:win10. 靶机:春秋云镜像-CVE-2022-0788. 写这个的时候在网上想查找下该漏洞的利用方式,没有找到相关的资料,因此记录下自己通过这个靶场的poc与exp. curl ' ...

  8. ATtiny88初体验(四):看门狗

    ATtiny88初体验(四):看门狗 ATtiny88单片机的看门狗使用内部独立的128KHz时钟源,拥有3种工作模式: Interrupt模式:超时产生中断: System Reset模式:超时产生 ...

  9. Linux-源码安装软件

    一.源码安装步骤 源码的安装一般由3个步骤组成:配置(configure).编译(make).安装(make install). 1.配置(configure) Configure是一个可执行脚本,它 ...

  10. windows下flutter的环境安装

    Flutter是谷歌出品的移动应用SDK,性能卓越.体验精美.跨平台.HotReload等等这些特点. Dart是谷歌推出的编程语言.支持即时编译JIT(Just In Time).HotReload ...