USE VECTORIZATION
矢量查询(Vectorized query) 每次处理数据时会将1024行数据组成一个batch进行处理,而不是一行一行进行处理,这样能够显著提高执行速度。
可以通过设置
set hive.vectorized.execution.enabled = true;
set hive.vectorized.execution.reduce.enabled = true;
开启来。
具体请参考:
[1] https://cwiki.apache.org/confluence/display/Hive/Vectorized+Query+Execution
COST BASED QUERY OPTIMIZATION
COST BASED QUERY OPTIMIZATION可以优化hive的每次查询。如果想要使用CBO,需要开启一下选项:
set hive.cbo.enable=true;
set hive.compute.query.using.stats=true;
set hive.stats.fetch.column.stats=true;
set hive.stats.fetch.partition.stats=true;
如果我们想要使用CBO,需要通过HIVE的分析模式来收集表的不同统计数据,我们可以通过下面的命令来进行:
analyze table tweets compute statistics for columns;
这样子,HIVE就可以通过消耗评估和不同的执行计划来让我们的查询跑的更快。
更多的查询请看这里.
WRITE GOOD SQL
SQL是一种强有力的解释性语言,在执行sql查询的时候,可以通过不同的sql语法来实现。虽然查询的结果是相同的,但是不同的SQL语句会有不同的性能表现。
例如,创建一个点击事件表,表中的每条记录都代表一个事件。
CREATE TABLE clicks (
timestamp date, sessionID string, url string, source_ip string
) STORED as ORC tblproperties (“orc.compress” = “SNAPPY”);
如果想要查询出每个sessionID 最后访问的url,一种可能的执行方式是这样的:
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;
上面的查询语句通过一个子查询获取每个sessionID最后的访问时间,然后通过inner join
来过滤到其它的事件。下面是另一种方法:
SELECT * FROM
(SELECT *, RANK() over (partition by sessionID,
order by timestamp desc) as rank
FROM clicks) ranked_clicks
WHERE ranked_clicks.rank=1;
第二种方法通过HIVE的开窗函数避免了两个大表的join,这样就能提高查询效率。