要利用Dataset
的优化,我是否必须明确使用Dataframe's
方法(例如df.select(col("name"), col("age")
等)或致电 任何 数据集的方法 - 甚至类似RDD的方法 (例如filter
,map
等)还可以进行优化吗?
答案 0 :(得分:2)
数据帧优化通常有三种形式:
钨内存管理
在定义RDD [myclass]时,spark并没有真正理解myclass是什么。这意味着通常每行都包含该类的实例。
这有两个问题。
第一个是对象的大小。 java对象有开销。例如,一个包含两个简单整数的case类。执行1000000个实例的序列并将其转换为RDD需要大约26MB,而使用数据集/数据框执行相同操作需要大约2MB。
此外,在数据集/数据帧中完成此内存不是由垃圾收集管理(它由内部通过spark管理为不安全内存),因此GC性能的开销会更少。
Dataset享有与数据帧相同的内存管理优势。也就是说,在进行数据集操作时,数据从内部(行)数据结构到案例类的转换会产生性能上的开销。
催化剂查询优化
使用数据帧功能时,spark会知道您要执行的操作,有时可以将查询修改为更有效的等效查询。
例如,假设您正在执行以下操作: df.withColumn(“a”,lit(1))。filter($“b”<($“a”+ 1))。
基本上你正在检查是否(x <1 + 1)。 Spark很聪明,可以理解这一点并将其更改为x <2。
使用数据集操作时无法完成这些操作,因为spark不知道您正在执行的函数的内部。
fullstage codegen
当spark知道你在做什么时,它实际上可以生成更高效的代码。在某些情况下,这可以将性能提高10倍。
这也无法在数据集函数上完成,因为spark不知道函数的内部。