Spark 2.0数据集与DataFrame

从火花2.0.1开始我有一些问题。 我读了很多文档,但到目前为止找不到足够的答案:

  • 有什么区别
    • df.select("foo")
    • df.select($"foo")
  • 我是否正确理解这一点
    • myDataSet.map(foo.someVal)是types安全的,不会转换为RDD但保持DataSet表示forms/无额外的开销(2.0.0性能)
  • 所有其他命令,如select,..只是语法糖。 它们不是types安全的,可以使用地图代替。 我怎么能df.select("foo")types安全没有地图声明?
    • 为什么我应该使用UDF / UADF而不是地图(假设地图停留在数据集表示中)?
  1. df.select("foo")df.select($"foo")之间的df.select("foo")是签名。 前者至less需要一个String ,后者是一个零个或多个Columns 。 除此之外,没有实际的区别。
  2. myDataSet.map(foo.someVal)是types安全的,但是任何Dataset操作都使用RDD并且与DataFrame操作相比,会有相当大的开销。 我们来看一个简单的例子:

     case class FooBar(foo: Int, bar: String) val ds = Seq(FooBar(1, "x")).toDS ds.map(_.foo).explain 
     == Physical Plan == *SerializeFromObject [input[0, int, true] AS value#123] +- *MapElements <function1>, obj#122: int +- *DeserializeToObject newInstance(class $line67.$read$$iw$$iw$FooBar), obj#121: $line67.$read$$iw$$iw$FooBar +- LocalTableScan [foo#117, bar#118] 

    正如你可以看到这个执行计划需要访问所有的字段,并且必须DeserializeToObject

  3. 没有。一般来说,其他方法不是语法糖,并产生显着不同的执行计划。 例如:

     ds.select($"foo").explain 
     == Physical Plan == LocalTableScan [foo#117] 

    与之前显示的计划相比,它可以直接访问列。 它不是API的限制,而是操作语义上的差异的结果。

  4. 我怎么能df.select(“富”)types安全没有地图声明?

    没有这样的select。 虽然键入的列允许您将静态Dataset转换为另一个静态types的Dataset

     ds.select($"bar".as[Int]) 

    没有types安全。 还有其他一些尝试包括types安全优化的操作, 如键入的聚合 ,但这个实验性的API。

  5. 为什么我应该使用UDF / UADF而不是地图

    这完全取决于你。 Spark中的每个分布式数据结构都有自己的优缺点。 就个人而言,我发现静态types的Dataset是最不有用的:

    • 不要提供与Dataset[Row]相同的优化范围(虽然它们共享存储格式和一些执行计划优化,但它不能完全从代码生成或堆外存储中受益),也不能访问所有分析functionDataFrame
    • 没有像RDDs那样灵活,只有一小部分本地支持的types。
    • Encoderstypes安全是有争议的。