首页 > 数据库 > 数据库开发技术 > 同事总写烂SQL,于是我出手了...
凌晨2点,报警群突然炸了——某核心业务库CPU飙到98%,交易系统响应延迟突破10秒。
我顶着黑眼圈打开AWR报告,发现一条"神秘SQL"正以每秒200次的频率疯狂吞噬着IO资源。
开发同事在群里弱弱发话:“这SQL跑测试环境明明很快啊…”
今天,我们就来揭秘那些让DBA“血压飙升”的烂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会先执行连接操作, 然后再进行过滤,(+)符号:使用(+)符号时, 查询的执行顺序是先过滤后连接。
某报表系统按“未填写备注”条件查询时,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;
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组件中的一种全文索引类型, 专为大文本字段的高效模糊查询设计
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或临时表方案
“烂SQL是DBA最好的老师,每个故障都是技术升级的契机。与其抱怨‘这届开发不行’,不如用工具链构筑护城河——毕竟,预防的成本永远低于抢救!”
"每个烂SQL都是送上门的教学案例,每次性能危机都是展现价值的战场。
记住:我们不是修电脑的,我们是数字世界的急诊科医生!"
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69947868/viewspace-3077909/ ,如需转载,请注明出处,否则将追究法律责任。