查询需要很长时间“不选择”

时间:2018-06-28 08:53:58

标签: apache-spark hive

我有一个查询,我很节俭地花了很长时间。我在具有50万行的表的单个分区上运行它。

查询如下:

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)&&(col1#607 = aaaa))
     +-* FileScan实木复合地板
表[col1#607,partition#611]
     批处理:true,
     格式:镶木地板,
     位置:PrunedInMemoryFileIndex [...,
     分区数:23,
     分区过滤器:[isnotnull(partition#611),
     (cast(partition#611 as int)= partition_name)],
     PushedFilters:[IsNotNull(col1),
     EqualTo(col1,aaaa)],
     ReadSchema:结构

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

* HashAggregate(keys = [],functions = [count(col0#625)])
  +-交换SinglePartition
     +-* HashAggregate(keys = [],functions = [partial_count(col0#625)])
        +-*项目[col0#625]
           +-*过滤器(isnotnull(col1#625)&&(col1#625 = aaaa))
              +-* FileScan实木复合地板
表[col1#625,partition#629]               批处理:true,
              格式:镶木地板,
              位置:PrunedInMemoryFileIndex [...,
              分区数:23,
              分区过滤器:[isnotnull(partition#629),
              (cast(partition#629 as int)= partition_name)],
              PushedFilters:[IsNotNull(col1),
              EqualTo(col1,aaaa)],
              ReadSchema:结构

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

修改

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

计数

  

18/06/28 11:42:55 INFO TaskSetManager:在阶段2509.0中启动任务0.0(TID 8092,ip-123456,执行程序36,分区0,RACK_LOCAL,5521个字节)
  18/06/28 11:42:55 INFO TaskSetManager:在阶段2509.0中启动任务1.0(TID 8093,ip-123456,执行程序35,分区1,RACK_LOCAL,5521个字节)
  18/06/28 11:42:55 INFO TaskSetManager:在阶段2509.0中启动任务2.0(TID 8094,ip-123456,执行程序36,分区2,RACK_LOCAL,5521个字节)
  18/06/28 11:42:55 INFO TaskSetManager:在阶段2509.0中启动任务3.0(TID 8095,ip-123456,执行程序35,分区3,RACK_LOCAL,5521个字节)
  18/06/28 11:42:55 INFO TaskSetManager:在阶段2509.0中启动任务4.0(TID 8096,ip-123456,执行程序36,分区4,RACK_LOCAL,5521个字节)
  18/06/28 11:42:55 INFO TaskSetManager:在阶段2509.0中启动任务5.0(TID 8097,ip-123456,执行程序35,分区5,RACK_LOCAL,5521个字节)
  18/06/28 11:42:55 INFO TaskSetManager:在阶段2509.0中启动任务6.0(TID 8098,ip-123456,执行程序36,分区6,RACK_LOCAL,5521个字节)
  18/06/28 11:42:55 INFO TaskSetManager:在阶段2509.0中启动任务7.0(TID 8099,ip-123456,执行程序35,分区7,RACK_LOCAL,5521个字节)
  18/06/28 11:42:55 INFO TaskSetManager:在阶段2509.0中启动任务8.0(TID 8100,ip-123456,执行程序36,分区8,RACK_LOCAL,5521个字节)
  18/06/28 11:42:55 INFO TaskSetManager:在阶段2509.0中启动任务9.0(TID 8101,ip-123456,执行程序35,分区9,RACK_LOCAL,5521个字节)

  • 不带:*
  

18/06/28 11:45:32 INFO TaskSetManager:在阶段2512.0中启动任务0.0 (TID 8136,ip-10-117-49-97.eu-west-1.compute .internal,执行程序37,分区1,RACK_LOCAL,5532字节)
  18/06/28 11:45:32 INFO BlockManagerInfo:在IP-10-117-49-97.eu-west-1.compute.internal:40489的内存中添加了broadcast_2352_piece0(大小:12.6 KB,可用空间:11.6 GB)
  18/06/28 11:45:32 INFO TaskSetManager:在ip上以667 ms在ip-10-117-49-97.eu-west-1.compute.internal(执行器37)上完成了阶段2512.0(TID 8136)中的任务0.0 (1/1)
  18/06/28 11:45:32 INFO YarnScheduler:从池中删除了任务已全部完成的TaskSet 2512.0
  18/06/28 11:45:32信息DA调度程序:ResultStage 2512(OperationManager.java:220中的getNextRowSet)在0.668 s中完成
  18/06/28 11:45:32 INFO DAGS计划程序:作业2293已完成:OperationManager.java:220中的getNextRowSet,耗时0.671740 s
  18/06/28 11:45:32 INFO SparkContext:开始作业:OperationManager.java中的getNextRowSet:220
  18/06/28 11:45:32信息DAscheduler:获得作业2294(OperationManager.java:220中的getNextRowSet)具有1个输出分区
  18/06/28 11:45:32 INFO DAGS计划程序:最后阶段:ResultStage 2513(OperationManager.java:220上的getNextRowSet)
  18/06/28 11:45:32 INFO DAGS日程表:最后阶段的父母:List()
  18/06/28 11:45:32 INFO DAGS日程表:父母失踪:List()
  18/06/28 11:45:32信息DAScheduler:提交ResultStage 2513(在AccessController.java:0上运行时运行MapPartitionsRDD [312]),没有丢失的父级
  18/06/28 11:45:32 INFO MemoryStore:阻止广播_2353作为值存储在内存中(估计大小66.6 KB,可用12.1 GB)
  18/06/28 11:45:32 INFO MemoryStore:块广播_2353_piece0作为字节存储在内存中(估计大小为12.6 KB,可用的12.1 GB)
  18/06/28 11:45:32 INFO BlockManagerInfo:在10.117.48.68:41493的内存中添加了broadcast_2353_piece0(大小:12.6 KB,可用空间:12.1 GB)
  18/06/28 11:45:32 INFO SparkContext:从DAGScheduler.scala:1047
的广播创建广播2353   18/06/28 11:45:32信息DAScheduler:从ResultStage 2513提交1个丢失的任务(MapPartitionsRDD [312]在AccessController.java:0上运行)(前15个任务用于分区
Vector(2))   18/06/28 11:45:32 INFO YarnScheduler:添加包含1个任务的任务集2513.0
  18/06/28 11:45:32 INFO TaskSetManager:在阶段2513.0中启动任务0.0 (TID 8137,ip-10-117-49-97.eu-west-1.compute.internal,执行程序37,分区2,RACK_LOCAL,5532个字节)
  18/06/28 11:45:33 INFO BlockManagerInfo:在IP-10-117-49-97.eu-west-1.compute.internal:40489的内存中添加了broadcast_2353_piece0(大小:12.6 KB,可用空间:11.6 GB)
  18/06/28 11:45:38 INFO TaskSetManager:在ip-10-117-49-97.eu-west-1.compute.internal(执行器37)上5238 ms的阶段2513.0(TID 8137)中完成了任务0.0 (1/1)
  18/06/28 11:45:38 INFO YarnScheduler:从池中删除了任务已全部完成的TaskSet 2513.0
  18/06/28 11:45:38信息DA调度程序:ResultStage 2513(OperationManager.java:220上的getNextRowSet)在5.238 s中完成
  18/06/28 11:45:38信息DAS计划程序:作业2294已完成:OperationManager.java:220上的getNextRowSet,耗时5.242084 s
  18/06/28 11:45:38 INFO SparkContext:开始作业:OperationManager.java上的getNextRowSet:220
  18/06/28 11:45:38信息DAscheduler:获得了2295个作业(OperationManager.java:220中的getNextRowSet)和1个输出分区
  18/06/28 11:45:38 INFO DAGS计划程序:最后阶段:ResultStage 2514(OperationManager.java:220上的getNextRowSet)
  18/06/28 11:45:38 INFO DAGS日程表:最后阶段的父母:List()
  18/06/28 11:45:38 INFO DAGS日程表:父母失踪:List()
  18/06/28 11:45:38信息DAScheduler:提交ResultStage 2514(在AccessController.java:0上运行时运行MapPartitionsRDD [312]),没有丢失的父级
  18/06/28 11:45:38 INFO MemoryStore:阻止广播_2354作为值存储在内存中(估计大小66.6 KB,可用12.1 GB)
  18/06/28 11:45:38 INFO MemoryStore:块广播_2354_piece0作为字节存储在内存中(估计大小12.6 KB,可用12.1 GB)
  18/06/28 11:45:38 INFO BlockManagerInfo:在10.117.48.68:41493的内存中添加了broadcast_2354_piece0(大小:12.6 KB,可用:12.1 GB)
  18/06/28 11:45:38 INFO SparkContext:从DAGScheduler.scala:1047
的广播创建广播2354   18/06/28 11:45:38信息DAScheduler:从ResultStage 2514(在AccessController.java:0上运行时运行MapPartitionsRDD [312])提交1个丢失的任务(前15个任务用于分区Vector(3))

(即,它重复执行此块,看起来像在计数情况下,它顺序地运行任务而不是并行运行)

我也尝试执行“ order by”,实际上使查询运行2倍更快


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

我在AWS Emr-5.11.1上运行节俭

配置单元2.3.2

火花2.2.1

节俭0.11.0

1 个答案:

答案 0 :(得分:1)

发现了问题。我有这个标志

spark.sql.thriftServer.incrementalCollect=true
thriftserver中的

。它按顺序收集每个工作人员的输出,这就是造成大量开销的原因。删除标志可解决此问题。我猜它被优化为在做“计数”时不按顺序执行,因为它不一定会有很多数据。