这是一个来自最近几天张大爷(张宏伟,Howard Zhang,SSC 首席工程师,性能优化组老专家)现场优化的案例。表名和部分关键字段做了化名处理。
原sql:
SELECT T1.col_1, T1.col_2 ,T1.col_3 ,T2.b_type,T1.VALID_DATE
FROM table_1 T1, table_2 T2
WHERE T1.SERV_TYPE = T2.SERVTYPE
and t1.valid_date = (select max(t3.valid_date)
from table_1 T3
where t3.col_1 = t1.col_1
and t3.col_2 = t1.col_2
and t3.col_3 = t1.col_3);
说明:table_1的col_1,col_2,col_3 联合起来对应了多个valid_date,先通过自关联取最大的valid_date。
改写后的sql:
SELECT T1.col_1, T1.col_2 ,T1.col_3 ,T2.b_type,T1.VALID_DATE
from
(select * from
(select t3.col_1,t3.col_2,t3.col_3,t3.valid_date,t3.SERV_TYPE,
ROW_NUMBER() OVER( PARTITION BY t3.col_1,t3.col_2,t3.col_3 ORDER BY t3.valid_date desc) as rr
from table_1 T3) where rr=1
) t1,table_2 T2 WHERE T1.SERV_TYPE = T2.SERVTYPE;
说明:
使用row_number分析函数,可以不需要自关联,只要一次扫描table_1表,即可实现需求。
老虎刘点评:
改写后的SQL要比原SQL效率提高几倍。但不是等价改写。
但是,改写后的SQL业务逻辑更严谨:原SQL如果table_1表相同col_1、col_2、col_3对应的最大valid_date有重复,则返回的结果也是有重复的,这应该不是SQL的本意。而改写后的SQL则不会返回重复记录。
如果一定要等价改写,可以使用max()分析函数。
总结:
开发者需要掌握一些高效的SQL写法,避免SQL低效又不严谨。再举个栗子:下面这个明显可以使用union all的sql,写成union就是在跟系统资源过不去了:
select col1,'typeA' as type from table1
union
select col1,'typeB' from table2
union
...
union
...
select col1,'typeN' from tableN;
本文分享自 老虎刘谈oracle性能优化 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!