4.2.2 除去多余的操作
操作场景
CREATE TABLE clicks
( timestamp date,
sessionID string,
url string,
source_ip string )
STORED as ORC
tblproperties (“orc.compress” = “SNAPPY”);
比如上边这个表,如果要获取每一个sessionID最新的访问记录,可以这样写:
SELECT clicks.*
FROM clicks inner join ( select sessionID, max(timestamp) as max_ts
from clicks
group by sessionID) latest
ON clicks.sessionID = latest.sessionID and clicks.timestamp = latest.max_ts;
语句解释:
查看执行计划会发现该语句会产生两个MapReduce,第一个MapReduce生成最新的sessionID信息表,第二MapReduce做一个Join,前面输出的结果与原表进行Join得到最后的结果。
再来看看下边的写法:
SELECT *
FROM ( SELECT *,
RANK() over (partition by sessionID, order by timestamp desc) as rank
FROM clicks
) ranked_clicks
WHERE ranked_clicks.rank=1;
语句解释:
查看执行计划会发现只会有一个MapReduce,该语句将数据读出来对sesssionID进行分组并按时间进行倒序排序,最后过滤出排序后的第一条记录。
比较第一个语句和第二个语句,发现第二个语句减少了一次MapReduce操作,性能自然大幅提升。很明显第一个语句多余执行了一次Join操作,第二语句以分组排序替代了Join,除去了不必要的Join操作,带来了性能的提升。