我是否必须明确使用Dataframe的方法来利用数据集的优化?

时间:2017-02-23 06:28:10

标签: java apache-spark apache-spark-sql apache-spark-dataset

要利用Dataset的优化,我是否必须明确使用Dataframe's方法(例如df.select(col("name"), col("age")等)或致电 任何 数据集的方法 - 甚至类似RDD的方法 (例如filtermap等)还可以进行优化吗?

1 个答案:

答案 0 :(得分:2)

数据帧优化通常有三种形式:

  1. 钨内存管理
  2. Catalyst查询优化
  3. wholestage codegen
  4. 钨内存管理

    在定义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不知道函数的内部。