我想将一个大表(超过150mln条记录和700列)从一个配置单元数据库传输到另一个配置单元数据库,其中包括一些转换,例如对日期列使用一个cast、对字符串列使用substr和一个简单的case语句。
比如说:
-- initial settings
SET hive.exec.dynamic.partition=true;
SET hive.exec.dynamic.partition.mode=nonstrict;
SET hive.exec.compress.intermediate=true;
SET hive.exec.parallel=true;
SET parquet.compression=SNAPPY;
SET hive.optimize.sort.dynamic.partition=true;
SET hive.merge.size.per.task=1000000000;
SET hive.merge.smallfiles.avgsize=1000000000;
INSERT INTO databaseA.tableName PARTITION(parition_col)
CASE WHEN a='Something' THEN 'SOMETHING'
WHEN a is null THEN 'Missing'
ELSE a END AS a,
column1,
column2,
...
cast(to_date(from_unixtime(unix_timestamp(),'yyyy-MM-dd')) AS string) AS
run_date,
substr(some_string, 1, 3)
FROM databaseB.tableName;
问题是这个查询将花费很多时间(每小时一百万行)。也许有人知道怎么加速?
我正在使用map reduce引擎执行此任务。
谢谢!
2条答案
按热度按时间u59ebvdq1#
关于如何加快查询速度的几点建议:
如果可能,请避免使用unix\u timestamp()。此函数是不确定的,会阻止查询的适当优化,它将在每个Map器或缩减器中执行,并可能返回不同的值。改用
当前日期()作为运行日期
有关更多详细信息,请参见此答案:https://stackoverflow.com/a/41140298/2700344
调整Map器和减速器的平行度。如果您的进程最终只有一个大文件(20gb)而不是几个小文件,那么显然没有足够的并行性。
对于Map器,请使用以下设置:
减少
hive.exec.reducers.bytes.per.reducer
增加减速器的数量。播放这些设置。成功的标准是更多的Map器/还原器,你的Map和还原阶段运行得更快。
有关详细信息,请参见此答案:https://stackoverflow.com/a/42842117/2700344
尝试添加
distribute by parition_col
它将根据分区键在缩减器之间分配数据,因此每个缩减器将创建更少的分区并消耗更少的内存。它也有助于避免太多的小输出文件。此设置应与一起使用hive.exec.reducers.bytes.per.reducer
避免减速器之间分布不均的问题,避免输出文件过大。a2mppw5e2#
既然配置单元表中的所有数据都是hdfs上的文件,为什么不直接将这些文件移动/复制到新表的hdfs位置呢。
例子: