暂无图片
暂无图片
1
暂无图片
暂无图片
1
暂无图片

同事总写烂SQL,于是我出手了...

开篇:一场由SQL引发的"血案"

凌晨2点,报警群突然炸了——某核心业务库CPU飙到98%,交易系统响应延迟突破10秒。
我顶着黑眼圈打开AWR报告,发现一条"神秘SQL"正以每秒200次的频率疯狂吞噬着IO资源。
开发同事在群里弱弱发话:“这SQL跑测试环境明明很快啊…”

今天,我们就来揭秘那些让DBA“血压飙升”的烂SQL,以及如何用专业技巧力挽狂澜。以下全是真实案例,建议转发给“肇事”同事!

案例1:多表关联的“混乱连接”

烂SQL场景:

财务系统多表关联查询耗时8分钟,表关联紊乱和FILTER操作

SELECT * FROM orders o, payments p   
WHERE o.order_id = p.order_id(+)  
AND o.user_id IN (SELECT user_id FROM blacklist);  
复制

问题分析:

1.外连接滥用,(+)语法导致优化器无法识别最佳连接顺序。‌

2.子查询未合并,IN子查询触发FILTER操作,循环执行百万次

优化方案:

改用ANSI JOIN语法:明确连接逻辑
SELECT * FROM orders o  
LEFT JOIN payments p 
ON o.order_id = p.order_id  
WHERE EXISTS
(SELECT 1 FROM blacklist 
b WHERE b.user_id = o.user_id);  

1.子查询合并,通过HASH JOIN替代FILTER循环
2.LEFT JOIN‌:LEFT JOIN会先执行连接操作,
然后再进行过滤,‌(+)符号‌:使用(+)符号时,
查询的执行顺序是先过滤后连接。
复制

案例2:NULL值查询的“隐形杀手”

烂SQL场景:

某报表系统按“未填写备注”条件查询时,10GB表全表扫描耗时180秒

SELECT * FROM contracts 
WHERE remark IS NULL;  
复制

问题分析:

单列索引失效:Oracle默认不索引NULL值,导致全表扫描。

复合索引漏洞:现有索引idx_contract未包含NULL值标识列。

优化方案:

1.创建NULL值专用索引:
通过常量占位符强制索引NULL记录
CREATE INDEX idx_remark_null 
ON contracts(remark, 0);  

2.改写查询条件:利用索引覆盖扫描
SELECT * FROM contracts 
WHERE remark IS NULL AND 0 = 0; 
复制

案例3:LOB字段全表扫

问题SQL:

SELECT * FROM contract 
WHERE PDF_CONTENT LIKE '保密协议%';  
复制

症状:频繁扫描CLOB字段拖垮IO

优化方案:

CREATE INDEX idx_contract_content ON contract(PDF_CONTENT)  
INDEXTYPE IS CTXSYS.CONTEXT;  

SELECT * FROM contract 
WHERE CONTAINS(PDF_CONTENT, '保密协议') > 0; 

说明:INDEXTYPE IS CTXSYS.CONTEXT
是Oracle Text组件中的一种全文索引类型,
专为大文本字段的高效模糊查询设计
复制

案例4:批量操作与事务

1.大事务导致UNDO表空间爆满
DELETE FROM billion_rows_table 
WHERE create_time < SYSDATE-365;

优化:分批次删除(每1万条提交),UNDO占用大大减小

2.低效的INSERT ALL批量插入
INSERT ALL INTO table_a VALUES (...) 
SELECT * FROM dual;  

优化:改用INSERT /*+ APPEND */直接路径插入,
速度提升10倍

3.TRUNCATE与DELETE选择失误
DELETE FROM error_data; 
-- 千万级数据 ,归档剧增

优化:改用TRUNCATE或临时表方案
复制

结语:DBA的生存法则

“烂SQL是DBA最好的老师,每个故障都是技术升级的契机。与其抱怨‘这届开发不行’,不如用工具链构筑护城河——毕竟,预防的成本永远低于抢救!”

"每个烂SQL都是送上门的教学案例,每次性能危机都是展现价值的战场。

记住:我们不是修电脑的,我们是数字世界的急诊科医生!"

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

文章被以下合辑收录

评论

老钢炮
暂无图片
8天前
评论
暂无图片 0
1.创建NULL值专用索引: 通过常量占位符强制索引NULL记录 CREATE INDEX idx_remark_null ON contracts(remark, 0); 这个骚操作可以的
8天前
暂无图片 点赞
评论
目录
  • 开篇:一场由SQL引发的"血案"
  • 案例1:多表关联的“混乱连接”
    • 烂SQL场景:
    • 问题分析:
    • 优化方案:
  • 案例2:NULL值查询的“隐形杀手”
    • 烂SQL场景:
    • 问题分析:
    • 优化方案:
  • 案例3:LOB字段全表扫
    • 问题SQL:
    • 优化方案:
  • 案例4:批量操作与事务
  • 结语:DBA的生存法则