在研发过程中,使用 Oracle 数据库时可能会遇到一些性能和兼容性的问题。以下是一些本人在工作期间曾遇到的关于Oracle的一些问题,希望可以帮助到有需要的同学们。
LISTAGG
语法拼接字符超长LISTAGG
语法拼接字符时,可能会遇到字符超长的情况,通常限制为 4000 字符。XMLAGG
进行改写,但其效率较慢,影响查询性能。XMLAGG
。在实际工作中,作者曾遇到过类似的复杂 SQL,在视图中进行了字段的范围查询,导致主查询通过 JOIN 操作连接这些视图时,视图中的数据过滤条件总是在执行笛卡尔积之后才生效,从而导致总体数据量特别大,严重影响查询性能。通过将视图中的范围查询改为 IN 或 = 进行值匹配,或者直接去掉视图并将视图那部分的 SQL 合并到主查询中,可以使过滤条件在早期阶段生效,显著减少中间结果集的数据量,提高查询效率。
“直击那个让执行计划发疯的魔鬼视图,用等值过滤利刃肢解笛卡尔积怪兽,见证SQL从30秒到0.8秒的惊天逆转”
正常来说分页场景,一般也就一页五六十条数据,所以oracle的10条一般大家是感受不到速度上的差异的,但一旦涉及到一次性查询全量的数据,这个差异一下子就出来了!
“那个优化FetchSize的深夜,我亲手把1小时的导出变成1分钟,仿佛听见Oracle在哭泣!”
特别是当这段sql写在存储过程的时候,就会出现问题,问题很玄学,至今不知道具体的答案。
– 旧写法(存在版本兼容问题)
SELECT str FROM( SELECT TO_CHAR(REGEXP_SUBSTR(a.strs ,'[^,]+',1,l))str FROM (SELECT p_idstrValue strs FROM dual) a, (SELECT LEVEL l FROM DUAL CONNECT BY LEVEL<=(...)) b ) GROUP BY str
优化后稳定版本:
– 新写法(通用稳定)
SELECT str FROM( SELECT TO_CHAR(REGEXP_SUBSTR(p_idstrValue ,'[^,]+',1,LEVEL))str FROM dual CONNECT BY LEVEL <= REGEXP_COUNT(p_idstrValue,',')+1 ) GROUP BY str
如果存在备份数据,或者恢复表数据的同学,一定要收藏下面的sql哦,说不定哪天就用上了~~~
--1、备份
CREATE TABLE T_TABLE_A_BF AS SELECT * FROM T_TABLE_A;
--2、启动表的row movement特性
ALTER TABLE T_TABLE_A ENABLE ROW MOVEMENT;
--3、闪回指定时间的快照
FLASHBACK TABLE T_TABLE_A TO TIMESTAMP
TO_TIMESTAMP('2023-07-14 10:50:00','yyyy-mm-dd hh24:mi:ss');
--4、关闭表的row movement功能
ALTER TABLE T_TABLE_A DISABLE ROW MOVEMENT;
Oracle性能更优且内置函数丰富,但国产化趋势下建议:
✅ 优先使用MySQL
✅ 业务逻辑在服务端实现
❌ 避免数千行存储过程
❌ 禁止用临时表做数据流转
血泪教训(懂得人都懂):
"曾经维护过几千行的Oracle存储过程,里面各种数据的流转、逻辑判断、临时表的插入删除,看的眼花缭乱,一个BUG排查了整整8小时!
在实际开发中,性能与功能往往需要进行权衡。鱼与熊掌不可兼得,很多时候我们无法同时追求极致的性能和丰富的功能。为了达到最佳的系统表现,我们需要根据具体的业务需求做出合理的选择。
如果这些经验让您少加了一次凌晨三点的班,请务必:
点赞让更多同行看见
⭐ 收藏防下次踩坑