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而不是地图(假设地图停留在数据集表示中)?
-
df.select("foo")
和df.select($"foo")
之间的df.select("foo")
是签名。 前者至less需要一个String
,后者是一个零个或多个Columns
。 除此之外,没有实际的区别。 -
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
。 -
没有。一般来说,其他方法不是语法糖,并产生显着不同的执行计划。 例如:
ds.select($"foo").explain
== Physical Plan == LocalTableScan [foo#117]
与之前显示的计划相比,它可以直接访问列。 它不是API的限制,而是操作语义上的差异的结果。
-
我怎么能df.select(“富”)types安全没有地图声明?
没有这样的select。 虽然键入的列允许您将静态
Dataset
转换为另一个静态types的Dataset
:ds.select($"bar".as[Int])
没有types安全。 还有其他一些尝试包括types安全优化的操作, 如键入的聚合 ,但这个实验性的API。
-
为什么我应该使用UDF / UADF而不是地图
这完全取决于你。 Spark中的每个分布式数据结构都有自己的优缺点。 就个人而言,我发现静态types的
Dataset
是最不有用的:- 不要提供与
Dataset[Row]
相同的优化范围(虽然它们共享存储格式和一些执行计划优化,但它不能完全从代码生成或堆外存储中受益),也不能访问所有分析functionDataFrame
。 - 没有像
RDDs
那样灵活,只有一小部分本地支持的types。 -
Encoders
types安全是有争议的。
- 不要提供与