HiveSQL查询优化

xiaoxiao2021-02-27  160

在讨论Hive优化之前,我们先介绍两个关键字‘EXPLAIN’和‘EXPLAIN EXTENDED’,在碰到复杂或者执行效率很低的查询时,在查询与居前加上这个关键字,此时这个查询不会执行,而是返回hive是如何去执行这个查询,hive会把查询分解成很多stage。理解这些stage可以帮助我们优化查询。

举个栗子:

EXPLAIN SELECT length(str_tel), str_tel FROM tmp_dataclean.tbl_fin_combine_protest ORDER BY length(str_tel);

1.优化之分区

对数据进行分区,可以将数据以一种符合逻辑的方式进行组织(比如分层存储),同时极大提高查询性能。

在创建表的时候,根据后续查询需求用'PARTITIOED BY( )'对数据进行合理的分区,下面我们根据‘province’和‘city’进行对数据进行分区分区:

CREATE TABLE IF NOT EXISTS tbl_per_info (no INT, name STRING, sex STRING, age INT, salary FLAOT) PARTITIONED BY (province STRING, city STRING);'province'和'city'已经在文件目录名称中了,不需要再把这些值放在目录下的文件中,浪费空间。当我们需要查询在山东德州的员工个人信息时: SELECT * FROM tbl_per_info WHERE province = '山东省' AND city = '德州市'

这时查询仅仅需要扫描山东省德州市这一个目录,其他省市的数据就都被忽略了。

2.优化之JOIN

Hive 默认查询中最后一个表是最大的表。在对每行记录进行连接操作时,会尝试将其他表缓存起来,然后扫描最后的表进行计算。 SELECT s.no, s.name, q.data FROM infos a JOIN datatime q ON s.no = q.no这里datatime这张表应该比info大。

在Hive里提供了一个“标记”机制来显式地告之优化器哪张表是大表,,这是不必在意表的前后问题:

SELECT /*+STREAMTABLE(q)*/ s.no, s.name, q.data FROM infos a JOIN datatime q ON s.no = q.no如果所有表中只有一个小表,那么可以在最大表通过mapper的时候将小表完全放到内存中 set hive.auto.convert.join=true; set jive.mapjoin.smalltable.filesize=fizesize;通过第一个属性设置来启用map_side JOIN,第二个属性可以配置优化的小表的大小 filesize

3.优化之本地模式

当数据集非常小时,通过本地模式在单台机器上处理所有任务,可以面下缩短执行时间,可以通过设置以下参数临时启用本地模式

set hive.exec.mode.local.auto=true;

4.优化之并行执行

Hive会将一个查询转化成多个阶段,包括MapReduce、limit、合并等,但一般一次只会执行一个阶段。当一些阶段不是完全依赖的时候,其实是可以并行执行的,这样job工作可以更快的完成。

set hive.exec.paralle=true;

5.优化之严格模式

通过设置下面的属性,可以启用严格模式,帮助我们避免执行一些不好的查询,包括:

(1)对于分区表,WHERE语句中没有分区字段过滤条件来限制查询范围;

(2)使用ORDER BY,而使用LIMIT;

(3)笛卡尔积查询。

set hive.mapred.mode=strict;

转载请注明原文地址: https://www.6miu.com/read-15881.html

最新回复(0)