我有一个蜂巢表,每小时插入几千个记录。但是当我执行select * from <table>
时,它需要花费很多时间来执行。这背后的原因是什么?
Hive开始并不快......不确定你期待什么,但它不会是毫秒级。
如果您想要性能改进,使用Tez或Spark而不是MapReduce执行,也可以使用Hive 2 w / LLAP,并以ORC或Parquet格式着陆数据。
如果您无法执行上述操作,请至少将数据放入每小时分区。然后实际查询分区而不是扫描所有行/列,因为Hive进行分区修剪。
此外,HDFS不喜欢小于hdfs块大小(128 MB)的文件。任何小的东西都意味着在地图任务中浪费了时间
如果你看一下Hive design and architecture,你会发现一个典型的查询会有一些开销。查询将被转换为用于分布式执行的代码,发送到集群后端,在那里执行,然后存储和收集结果以供显示。即使输入数据和最终结果集很小,这也会增加每个查询的延迟。
我同意使用执行引擎tez / spark的@ cricket_007。您可以从最终实现一些自定义,以实现hive中的性能:
set hive.vectorized.execution.enabled = true;
set hive.vectorized.execution.reduce.enabled = true;
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;
最佳做法是对数据进行分区以加快查询速度。分区将使hive对数据子集而不是整个数据集运行查询。创建分区可以按如下方式完成:
文件夹结构应如下所示:
path/to/directory/partition=partition_name
然后在表本身(假设它在外部表上),你创建表语句应该是这样的:
CREATE EXTERNAL TABLE table_name (
...
fields
...
)
PARTITIONED BY (partition)
LOCATION '/path/to/directory'
然后,您可以查询该表并将该分区视为另一列。