一个非常不友好的SQL的优化改写
来源:互联网 发布:歌华有线网络 编辑:程序博客网 时间:2024/05/16 12:29
这个SQL 是在项目中遇到, 性能非常不好, 隐患非常之大。 可理解程度非常不好, 优化难度一般但真正 和业务关联后 优化程度 还可以。
另外 主要涉及 到行列转化, 和在分组数据中 提取数据。 主要是
首先 原来的SQL 。。
with sql1 as (select vpfi.code code from t_p_info vpfi where vpfi.pm = '张三')select * from
(select opp.username as user_name,
(select oi.insit_name from wbj_org_insit oi where oi.insit_id = oip.insit_id) as dname,
ea.pcode as pcode,
(select min(decode(tt.type,'出差',nvl(tt.city, tt.type), tt.type)) from T_ATTENDANCE tt where tt.eid = opp.username and tt.date = '2015-08-01' ) as data_1,
--..... 依次
(select min(decode(tt.type,'出差',nvl(tt.city, tt.type), tt.type)) from T_ATTENDANCE tt where tt.eid = opp.username and tt.date = '2015-08-31' ) as data_31
from t_per opp
left join t_post oip on opp.pid = oip.pid
left join t_attendance ea on ea.eid = opp.username and ea.month = '2015-08'
left join sql1 t1 on t1.code = ea.P_CODE
where oip.t_isldr > 0 and t1.code is not null and ( ea.RECORDER = '张三' or ea.emp_id = '张三')
group by opp.username, oip.insit_id ,ea.prj_code )
where 1=1 order by 2, 1 ;
原来的SQL 有 32 个标量子查询......另外表名写法也不统一, 看到这个SQL 大骇.... 还是看了一下执行计划.... t_attendance 扫描多次, 逻辑读, 物理读 很多次。 T_ATTENDANCE 表如果数据量 很大, 哥可以保证, 这个SQL 跑死。。 这个表 扫描 30多次, 用的了吗?? 另外 (select oi.insit_name from wbj_org_insit oi where oi.insit_id = oip.insit_id) as dname, 谁能保证 值是唯一的??? 当然业务上面原则是唯一的?? 但谁能 保证 数据库中值不会出现脏数据???( 库中没有唯一检查约束) ,另外之前 select min(decode(tt.type,'出差',nvl(tt.city, tt.type), tt.type)) from T_ATTENDANCE tt where tt.eid = opp.username and tt.date = '2015-08-01' ) 出现过脏数据,出错了, 所有 加了 min , 执行计划就不 贴出来了。。。。反正是 乱的 不太想看........( 还有一个原因是 哥已经知道性能问题在哪, 另外改写什么的都知道大致怎么改写了, 所以哥不想看执行计划了。。。 兄弟们有时候还是要看执行计划的........ )
还有 left join sql1 t1 on t1.code = ea.P_CODE where 后面 and t1.code is not null , 什么逻辑||||| 有用left join 又用 t1.code is not null ,,, 不如换成 inner join 去掉后面的 is not null 条件!!!!!
还有一个问题是既然 是 group by 了。。。 就不要 order by , 因为 10 g 11g 中group by oracle 内部是排序 好的, 单官方的文档没有保证是的, 另外我们这边的业务上面 没有排序也满足... 那就不要 排序了.....
于是改写后的 语句
with sql1 as (select code from t_p_info vpfi where vpfi.pm = '张三')
select username, ea.pcode as pcode, oi.insit_name,
min( decode( date,'2015-08-01',decode(type,'出差',nvl(city, type), type) ) ) day1,
--- 一次31
min( decode( date,'2015-08-31',decode(type,'出差',nvl(city, type), type) ) ) day31
from t_per opp
inner join t_post oip on opp.pid = oip.pid
left join _insit oi on oi.insit_id = oip.insit_id
left join t_attendance ea on ea.emp_id = opp.username
inner join sql1 t1 on t1.code = ea.PCODE
where oip.t_isldr > 0 and ( ea.RECORDER = '张三' or ea.emp_id = '张三')
and ea.month = '2015-08'
group by opp.username, oi.insit_name ,ea.prj_code;
改写后的执行计划也不贴出来了。。。。 避免了 上述的全部问题 , t_attendance 只扫描了1次, 在分组中取数据是 min, 等聚合函数取数据,
decode 行列 转换。 执行逻辑读 是原来的 1/10 这样。。。。 物理读 减少的也差不多》。
decode( date,'2015-08-31',decode(type,'出差',nvl(city, type), type) ) 改换成 coalesce( nullif('出差', type),city, type) 好一点
- 一个非常不友好的SQL的优化改写
- 一个简单的优化改写
- 一个sql语句的改写
- SQL优化-标量子查询的改写
- 百度对wordpress博客非常不友好的原因
- SQL优化之基于SQL特征的改写
- 改写TCPMP的界面非常简单
- 改写SQL优化SQL
- 发现CSDN的一个操作不友好的功能
- 一次非常有意思的sql优化经历
- 一次非常有意思的 SQL 优化经历
- 一次非常有意思的sql优化经历
- 一次非常有意思的SQL优化经历
- 一次非常有意思的 SQL 优化经历
- 一次非常有意思的sql优化经历
- 一次非常有意思的SQL优化经历
- 一次非常有意思的 SQL 优化经历
- 一次非常有意思的 SQL 优化经历
- 骗子
- 黑马程序员-java基础-去除ArrayList中重复的字符串
- 数据库插入datetime数据的java展示
- Codeforces Round #125 (Div. 1) A. About Bacteria
- WordPress 主题框架是如何工作的
- 一个非常不友好的SQL的优化改写
- JAVA实现验证码
- Spring整合Mongdb,实现基本的增,删,查,改
- FFMPEG_avi转码到mp4(aac+h264)源码
- 简化实现动态行列转置的SQL
- py2exe使用方法详解 Python生成exe步骤
- 堆栈,堆和栈的区别
- java学习之内部类
- elasticsearch-rtf 1.7.1