【问题标题】:Performance of Spark DataFrame with spark sqlSpark DataFrame 与 spark sql 的性能
【发布时间】:2016-02-03 12:18:15
【问题描述】:

我想通过减少数据库周期和内存来有效地使用 spark DataFrame。

这里我提供了示例代码。 (不是完整的实现)

Map<String, String> options = new HashMap<>();
options.put("dbtable", ("select * from TestTable");

//Create the dataframe
DataFrame df1 = sqlContext.read().format("jdbc").options(options).load();
df1.registerTempTable("TestDBFrame");

//Query1
DataFrame df2 =sqlContext.sql("SELECT name FROM TestDBFrame WHERE age >= 10");

//Query2
DataFrame df3 =sqlContext.sql("SELECT name FROM TestDBFrame WHERE age >= 50");

//df2 operation 
df2.count

//df3 operation 
df3.count
  1. 在运行 query1 和 query2 时,对 DB 有多少次命中?是否两次命中数据库?

  2. 当我们根据最初创建的数据帧访问 df2 和 df3 数据帧的计数时,它是再执行两次 DB 还是只是从内存中加载?

由于我需要优化数据库周期和内存,希望对此有更好的解释。

【问题讨论】:

    标签: apache-spark apache-spark-sql


    【解决方案1】:

    在运行 query1 和 query2 时,对 DB 有多少次命中?是否两次命中数据库?

    零次。由于以上都不会触发操作,因此当您调用load时,除了初始元数据获取之外无需访问数据库

    当我们根据最初创建的数据帧访问 df2 和 df3 数据帧的计数时,它是再执行两次 DB 还是只是从内存中加载?

    DataFrame 上的每个操作都将访问数据库。如果你想最小化数据库命中,你应该考虑缓存表。它不会阻止数据库访问,但应尽量减少不必要的流量

    您必须记住,它并不能提供强有力的保证。在使用外部源时,Spark SQL 包括多项优化。例如df2.countdf3.count 将下推谓词,因此不会有适合缓存的数据。可以尝试隔离下游DataFrames如下:

    DataFrame df1 = sqlContext.read().format("jdbc")
      .options(options).load().where(lit(true))
    df1.registerTempTable("TestDBFrame");
    sqlContext.cacheTable("TestDBFrame");
    

    如果在第一次访问时有足够的内存完整的表,它应该获取并缓存。请记住,在实践中,它的效率可能低于让谓词下推完成的工作。

    如果您想要强有力的保证,您应该先从数据库中导出数据,然后再在 Spark 中读取数据。

    附带说明,您使用的子查询似乎缺少别名。

    【讨论】:

    • 您好 Zero323,感谢您的明确解释。我赞成你的回答。但有些事情需要澄清。 1.“它不会阻止数据库访问,但应该尽量减少不必要的流量”是什么意思。 2. “请记住,在实践中它可能比让谓词下推完成它的工作效率低。”
    • 1.缓存与其说是保证,不如说是一种暗示。可能没有足够的空间,数据可能会被驱逐。例如,请参阅我的答案stackoverflow.com/a/34117788/1560062 2. Spark SQL 执行多项优化。加载一小部分数据比获取整个表并稍后过滤要高效得多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-18
    • 2016-06-10
    • 2020-03-18
    • 1970-01-01
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    相关资源
    最近更新 更多