暂无图片
暂无图片
3
暂无图片
暂无图片
2
暂无图片

oracle19C数据库一条正则函数语句的优化

原创 11 0 2023-09-01
163

环境描述: linux 7.6 + oracle 19C

前几日,软件做了新功能的发布后,数据库的awr报告里出现一条很慢的语句(表名、列名做了替换):


select count(t1.bxbm) from ( select yy as bxbm from (with t as (select id x, bxbm y from uf_testxxx ) select x, regexp_substr(y, :"SYS_B_00", :"SYS_B_01", level) yy from t where instr(y, :"SYS_B_02") >= :"SYS_B_03" connect by level <= regexp_count(y, :"SYS_B_04") + :"SYS_B_05" and y=prior y and prior dbms_random.value is not null ) group by yy )t1, ( SELECT REGEXP_SUBSTR(:"SYS_B_06", :"SYS_B_07", :"SYS_B_08", LEVEL, :"SYS_B_09") AS bxbm FROM DUAL CONNECT BY LEVEL <= LENGTH(:"SYS_B_10") - LENGTH(REGEXP_REPLACE(:"SYS_B_11", :"SYS_B_12", :"SYS_B_13"))+:"SYS_B_14" )t2 where t1.bxbm = t2.bxbm;


经过统计,表uf_testxxx的记录1000多。

该语句每次执行2000多秒。

经过测试,该语句在Oracle11G上运行正常,不到1秒.

可以确定是19c的bug.


优化的思路是使用表连接替换递归。

select count(t1.bxbm)

from (
select yy as bxbm
from (with t as (select id x, bhbm y
from uf_testxxx where bxbm is not null)
select x, regexp_substr(y, :"SYS_B_00", :"SYS_B_01", le) yy
from t,( select level le from dual connect by level <= 200) b
where b.le <= length(y) - length(replace(y,',','')) +1 and regexp_substr(y, '[^,]+', 1, b.le) is not null
)
group by yy
)t1, (
SELECT REGEXP_SUBSTR(:"SYS_B_06", :"SYS_B_07", :"SYS_B_08", LEVEL, :"SYS_B_09") AS bxbm
FROM DUAL
CONNECT BY LEVEL <=
LENGTH(:"SYS_B_10") - LENGTH(REGEXP_REPLACE(:"SYS_B_11", :"SYS_B_12", :"SYS_B_13"))+:"SYS_B_14"
)t2 where t1.bxbm = t2.bxbm;


其中的200,是根据业务情况下确定的。经过分析,业务数据最大分隔是145个,取200完全可以满足业务的需求。

优化后的效果是每次执行0.7秒.


最后修改时间:2023-09-01 17:08:14
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

星星之火
暂无图片
11月前
评论
暂无图片 0
你有什么样的心态,就有什么样的人生,学会放下,看开 想开,明天依旧阳光灿烂。 ​​​
11月前
暂无图片 点赞
评论
展翅凌云
暂无图片
1年前
评论
暂无图片 0
学习了,非常的不错
1年前
暂无图片 点赞
评论