我正在使用Hive with Spark 1.6.3
我有一个大型数据集(40000行,20列左右,每列包含500字节--3KB数据)
查询是3个数据集的连接
我希望能够分页最终的连接数据集,并且我发现我可以使用row_number() OVER (ORDER BY 1)
为数据集中的每一行生成唯一的行号。
在此之后我可以做到
SELECT * FROM dataset WHERE row between 1 AND 100
但是,有些资源建议不要使用ORDER BY
,因为它将所有数据放入1个分区(我可以看到在shuffle分配将数据移动到一个分区的日志中就是这种情况),当发生这种情况时,我会遇到内存异常。
我如何以更有效的方式浏览数据集?
我启用了persist - MEMORY_AND_DISK
,这样如果分区太大,它就会溢出到磁盘上(对于某些转换,我可以看到至少有一些数据溢出到磁盘上,当我不使用row_number()
)
答案 0 :(得分:0)
好吧,您可以在最终的联接数据框中应用this method。
您还应该将数据帧保留为文件以保证排序,因为重新评估可能会创建different order。
答案 1 :(得分:0)
一种策略可以是首先仅选择数据集的unique_key,并仅对该数据集应用row_number函数。由于您从大型数据集中选择单个列,因此它很可能适合单个分区。
val dfKey = df.select("uniqueKey")
dfKey.createOrUpdateTempTable("dfKey")
val dfWithRowNum = spark.sql(select dfKey*, row_number() as row_number OVER (ORDER BY 1))
// save dfWithRowNum
完成uniqueKey上的row_number操作后;保存该数据帧。现在在下一阶段将此数据帧与更大的数据帧连接,并将row_number列附加到该数据帧。
dfOriginal.createOrUpdateTempTable("dfOriginal")
dfWithRowNum.createOrUpdateTempTable("dfWithRowNum")
val joined = spark.sql("select dfOriginal.* from dfOriginal join dfWithRowNum on dfOriginal.uniqueKey = dfWithRowNum.uniqueKey")
// save joined
现在您可以查询
SELECT * FROM joineddataset WHERE row between 1 AND 100
对于MEMORY_DISK的持久性,我发现偶尔因内存不足而失败。我宁愿使用DISK_ONLY,虽然执行得到保证,但性能会受到惩罚。