配置单元查询优化

6l7fqoea  于 2021-05-29  发布在  Hadoop
关注(0)|答案(3)|浏览(319)

当源数据文件附加新记录时,必须每天从配置单元中的外部表向内部表执行增量加载。可以根据时间戳(列)筛选出新记录 load_ts 在table上)他们被加载。试图通过从源表中选择负载大于当前值的记录来实现这一点 max(load_ts) 在目标表中,如下所示:

INSERT INTO TABLE target_temp PARTITION (DATA_DT)
SELECT ms.* FROM temp_db.source_temp ms 
JOIN (select max(load_ts) max_load_ts from target_temp) mt
ON 1=1
WHERE
ms.load_ts > mt.max_load_ts;

但是上面的查询没有给出所需的输出。执行需要很长时间(map-reduce范式不应该是这种情况)。
尝试过其他场景,比如 max(load_ts) 作为变量,而不是连接。性能仍然没有改善。如果有人能给出他们的见解,说明这种方法中可能不正确的地方,并提供其他解决方案,那将非常有帮助。

ioekq8ef

ioekq8ef1#

通过启用以下属性,使用基于成本的优化技术

set hive.cbo.enable=true;
set hive.stats.autogather=true;
set hive.stats.fetch.column.stats=true;
set hive.compute.query.using.stats=true;
set hive.vectorized.execution.enabled=true;
set hive.exec.parallel=true;

阿劳分析表格

ANALYZE TABLE temp_db.source_temp COMPUTE STATISTICS [comma_separated_column_list];
ANALYZE TABLE target_temp PARTITION(DATA_DT) COMPUTE STATISTICS;
vhipe2zx

vhipe2zx2#

首先,map/reduce模型不能保证您的查询花费更少的时间。其主要思想是,它的性能将随着节点数的增加而线性扩展,但是您仍然需要考虑如何操作,这比在普通sql中更重要。
首先要检查源表是否按时间分区。如果不是的话,它应该像你每次读整张table一样。第二,你每次都在计算最大值,同样,在整个destination表上。如果你只计算最后一个分区的最大值,你可以使它快很多,所以改变这个

JOIN (select max(load_ts) max_load_ts from target_temp) mt

对于这个(你没有写分区列,所以我假设它叫做'dt'

JOIN (select max(load_ts) max_load_ts from target_temp WHERE dt=PREVIOUS_DATA_DT) mt

因为我们知道最大负载在最后一个分区。
否则,如果不知道源表的结构,以及像其他人评论的那样,两个表的大小,就很难提供帮助。

t3psigkw

t3psigkw3#

join比where子句中的variable慢。但这里的主要性能问题是,您的查询对目标表和源表执行完全扫描。我建议:
仅查询最新分区的max(load\ts)。
启用统计信息收集和使用

set hive.compute.query.using.stats=true;
set hive.stats.fetch.column.stats=true;
set hive.stats.fetch.partition.stats=true;
set hive.stats.autogather=true;

计算两个表中列的统计信息。统计信息将使选择max(partition)或max(ts)之类的查询执行得更快
如果适用,请尝试将源分区文件放入目标分区文件夹,而不是插入(目标和源表分区和存储格式应启用此功能)。例如,对于textfile存储格式和源表分区仅包含rows>max(目标分区)时,它可以正常工作。您可以将copy files方法(对于那些完全包含要插入而不进行筛选的行的源分区)和insert方法(对于包含需要进行筛选的混合数据的分区)结合起来。
在插入过程中,配置单元可能正在合并文件。此合并阶段需要额外的时间并添加额外的阶段作业。选中hive.merge.mapredfiles选项并尝试将其关闭。
当然,使用预先计算的变量而不是join。

相关问题