我正在使用Impala JDBC驱动程序将数据批量插入Impala。我目前的批处理大小为1000,并使用PreparedStatement的INSERT INTO VALUES子句来执行批处理查询。 Impala守护程序在3台计算机上运行,而Impala目录服务器,状态存储正在第4台计算机上运行。
Impala上的批量插入查询计划如下所示:
Query Timeline: 35s398ms
- Query submitted: 0.000ns (0.000ns)
- Planning finished: 34s822ms (34s822ms)
- Submit for admission: 34s886ms (63.997ms)
- Completed admission: 34s886ms (0.000ns)
- Ready to start 1 fragment instances: 34s886ms (0.000ns)
- All 1 fragment instances started: 34s958ms (71.997ms)
- DML data written: 35s082ms (123.996ms)
- DML Metastore update finished: 35s286ms (203.993ms)
- Request finished: 35s298ms (11.999ms)
- Unregister query: 35s374ms (75.997ms)
- ComputeScanRangeAssignmentTimer: 0.000ns
正如我们所看到的,计划完成正在全力以赴。我们尝试过以两种格式创建PARQUET和普通格式。但每次规划完成部分都太高了。
我需要更改配置吗?或者我做错了什么?
答案 0 :(得分:2)
首先要注意的是,即使您批量使用单个PreparedStatement
,每行仍将获得自己的INSERT语句。例如,准备好的声明
INSERT INTO t VALUES (?, ?);
将插入两行
INSERT INTO t VALUES ('a', 1);
INSERT INTO t VALUES ('b', 2);
而不是
INSERT INTO t VALUES ('a', 1), ('b', 2);
接下来要考虑的是,在Hadoop中插入单行效率非常低,因为必须为每一行创建一个新的HDFS文件。
INSERT ... VALUES
技术不适合将大量数据加载到基于HDFS的表中,因为插入操作无法并行化,并且每个都生成一个单独的数据文件。使用它来设置小维度表或少量数据以试验SQL语法或HBase表。不要将它用于大型ETL作业或负载操作的基准测试。不要运行包含数千个INSERT ... VALUES
语句的脚本,每次都插入一行。如果您运行INSERT ... VALUES
操作以将数据作为ETL管道中的一个阶段加载到临时表中,请在每个VALUES
子句中包含多个行值(如果可能),并使用单独的数据库使清理更容易该操作确实产生了许多小文件。
答案 1 :(得分:0)
通过对多行使用一个 insert
语句来加载数据的示例代码:
USE my_schema
;
DROP TABLE IF EXISTS my_countries
;
CREATE TABLE IF NOT EXISTS my_countries (
country_id int
, country_name string
)
;
INSERT INTO my_countries VALUES
( 1, 'UK')
, ( 2, 'USA')
;
答案 2 :(得分:0)
为了更好的性能;
如果你让 hadoop 集群处理插入而不是你的机器,这将是一个更好的性能。