查询需要很长时间"选择"任何内容



我有一个在节俭中运行的查询,它需要很长时间。我在一个有500k行的表的单个分区上运行它。

查询如下:

select col0 from <table> where partition=<partition> and <col1>=<val>

我把它设为col1 != val,所以查询返回0行。

这个查询大约需要30秒(如果我使用select *,则需要一分钟)。

当我运行完全相同的查询,但使用select count(col0)时,需要2秒。

是什么原因导致select col的查询耗时较长,而select count(col)的查询耗时不长

以下是解释的问题

explain select col0 from table where `partition` = partition and col=val;

*项目[col0#607]
+-*筛选器(isnotnull(col1#607)&amp;(col1#607=aaaa)
+-*FileScan镶木地板
table[col1#607,partition#611]
批处理:true,
格式:镶木地板,
Location:PrunedInMemoryFileIndex[…,
1PartitionCount:23,
2PartitionFilters:[isnotnull(partition#612),
3(cast(partition#611 as int)=partition_name)],
PushedFilters:[isnotnull(col1),
EqualTo(col1,aaaa)],
0ReadSchema:结构

explain select count(col0) from table where `partition` = partition and col=val;

*HashAggregate(keys=[],functions=[count(col0#625)])
+-Exchange SinglePartition
+/-*HashAg胶gate(keys=[],functions=[partial_count(col0#525)])
+-*Project[col0#625]
+/-*Filter(isnotnull(col1#625)&amp;(col1#625=aaaa))
+-*FileScan镶木地板
表[col1#625,分区#629]批处理:true,
格式:Parquet,
Location:PrunedInMemoryFileIndex[…,
1PartitionCount:23,
2PartitionFilters:[isnotnull(分区#629),<br](强制转换(分区#621为int)>3PushedFilters:[isnotnull(col1),
EqualTo(col1,aaaa)],
ReadSchema:struct

据我所知,过程完全相同,只有count查询有更多步骤。那它怎么会快15倍呢?

编辑

我在日志中发现了这个有趣的金块:

计数

18/06/28 11:42:55 INFO TaskSetManager:在阶段2509.0中启动任务0.0(TID 8094,ip-123456,执行器36,分区2,RACK_LOCAL,5521字节)
18/06/28 11:42:55信息任务集管理器:在阶段2509.0中启动任务3.0TaskSetManager:在阶段2509.0中启动任务5.0(TID 8097,ip-123456,executor 35,partition 5,RACK_LOCAL,5521字节)
18/06/28 11:42:55 INFO TaskSetManager:在阶段2509.0中启动任务6.0(TID 8099,ip-123456,执行器35,分区7,RACK_LOCAL,5521字节)
18/06/28 11:42:55信息任务集管理器:在阶段2509.0中启动任务8.0

  • 不带:*

18/06/28 11:45:32 INFO TaskSetManager:在阶段2512.0中启动任务0.0(TID 8136,ip-10-117-49-97.eu-west-1.compute.internal,executor 37,partition 1,RACK_LOCAL,5532字节)
18/06/2811:45:32INFO BlockManagerInfo:在ip-10-117-17-49-97上的内存中添加broadcast_2352_piece0。eu-west-1-compute.ininternal:40489(大小:12.6 KB,可用空间:11.6 GB)
18/06/2811:45:32 INFO TaskSetManager:在ip-10-117-49-97.eu-west-1.compute.internal(executor 37)(1/1)上667毫秒内完成了阶段2512.0(TID 8136)中的任务0.0
18/06/28 11:45:3 2 INFO YarnScheduler:删除了任务集2512.0,其任务已全部完成,来自池
18/06/28 11:45:32信息DAGScheduler:ResultStage 2512(OperationManager.java:220处的getNextRowSet)在0.668秒内完成
18/28 11:45:30信息DAGSscheduler:作业2293完成:OperationManager.java处的getNext RowSet,耗时0.671740秒
18/06/28 11:45:32 INFO SparkContext:开始作业:OperationManager.java:220
18/06/28 11:45:302 INFO DAGScheduler:获得作业2294(OperationManager.java处的getNextRowSet)和1个输出分区
18:06/28 10:45:32 INFO-DAGScheduler:最终阶段:ResultStage 2513最后阶段的父级:List()
18/06/28 11:45:32 INFO DAGScheduler:缺少父级:List
18/28 11:45:30 INFO DAGS cheduler:Submit ResultStage 2513(MapPartitionsRDD[312]在AccessController.java:0上运行),它没有丢失的父级
18/06/28 11:45:32 INFO MemoryStore:块broadcast_2353作为值存储在内存中(估计大小66.6 KB,可用12.1 GB)
18/28 11:45:30 INFO memory Store:块broadcast_2353_piece0作为字节存储在内存(估计大小12.6 KB,可用12.1GB)
18/06:28 11:45:12 INFO BlockManager信息:于10.117.48.68:41493在内存中添加broadcast_3353_piece 0(大小:12.6 KB,可用空间:12.1 GB)
28年6月18日11:45:32 INFO SparkContext:从DAGScheduler上的广播创建广播2353。scala:1047
18年6日11:45:30 INFO DAGScheduler:提交ResultStage 2513中缺少的1个任务(在AccessController.java:0上运行的MapPartitionsRDD[312])(前15个任务用于分区
Vector(2))18/06/28 11:45:32 INFO YarnScheduler:添加带有1个任务的任务集2513.0
18/06/28 12:45:32信息任务集管理器:在阶段2513.0中启动任务0.0(TID 8137,ip-10-117-49-97.eu-west-1.compute.internal,executor 37,partition 2,RACK_LOCAL,5532字节)
18/28 11:45:30信息块管理器信息:在上的内存中添加broadcast_2353_piece0ip-10-117-49-97.eu-west-1.compute.internal(executor 37)(1/1)
18/06/28 11:45:38 INFO TaskSetManager:删除了任务集2513.0,其任务已全部完成,来自池
18/06/28 11:45:38 INFO DAGScheduler:ResultStage 2513(OperationManager.java:220处的getNextRowSet)在5.238秒内完成
18/28 11:45:30 INFO DAGS cheduler:作业2294完成:OperationManager.java处的getNext RowSet,耗时5.242084秒
18/06/28 11:45:38 INFO SparkContext:开始作业:OperationManager.java:220
18/28 11:45:308 INFO DAGScheduler:获得作业2295(OperationManager.java处的getNextRowSet)和1个输出分区
18:06/28 10:45:38 INFO-DAGScheduler:最终阶段:ResultStage 2514最后阶段的父级:List()
18/06/28 11:45:38 INFO DAGScheduler:缺少父级:List
18/28 11:45:30 INFO DAGS cheduler:Submit ResultStage 2514(MapPartitionsRDD[312]在AccessController.java:0上运行),它没有丢失的父级
18/06/28 11:45:38 INFO MemoryStore:块broadcast_2354作为值存储在内存中(估计大小66.6 KB,可用12.1 GB)
18/28 11:45:30 INFO memory Store:块broadcast_2354_piece0作为字节存储在内存(估计大小12.6 KB,可用12.1GB)
18/06:28 11:45:8 INFO BlockManager信息:于10.117.48.68:41493在内存中添加broadcast_3354_piece 0(大小:12.6 KB,可用空间:12.1 GB)
28年6月18日11:45:38 INFO SparkContext:从DAGScheduler的广播创建广播2354。scala:1047
18年6日11:45:30 INFO DAGScheduler:提交ResultStage 2514中缺少的1个任务(在AccessController.java:0上运行的MapPartitionsRDD[312])(前15个任务用于分区Vector(3))

(即,它重复这个块,看起来像是按顺序运行任务,而不是像计数情况下那样并行)

我还尝试过"按顺序",它实际上使查询运行速度快了2倍


使用spark而不是节俭对相同的数据运行相同的查询要快得多。

我在aws emr-5.11.1 上运行节俭

蜂巢2.3.2

Spark 2.2.1

节俭0.11.0

发现问题。我有这面旗帜

spark.sql.thriftServer.incrementalCollect=true

在节俭服务器中。它按顺序收集每个工人的输出,这就是造成这种巨大开销的原因。删除标志解决了此问题。我想它被优化为在进行"计数"时不按顺序进行,因为它一定不会有很多数据。

最新更新