delta-lake - 如何有效地对 Delta 表进行分区?

标签 delta-lake

在增量表中存储我的数据帧时,为我的数据帧寻找有效的分区策略。

我当前的数据帧 1.5000.000 rowa 将数据从数据帧移动到增量表需要 3.5 小时。

为了寻找更有效的写作方式,我决定尝试将我的表的不同列作为分区列。我搜索了我的列的基数并选择了以下列。

column1 = 有 3 个 distinct_values
column2 = 有 7 个不同的值
column3 = 有 26 个不同的值
column4 = 有 73 个不同的值
column5 = 有 143 个不同的值
column6 = 有 246 个不同的值
column7 = 有 543 个不同的值

集群:64GB,8核

在我的笔记本中使用以下代码

df.write.partitionBy("column_1").format("delta").mode("overwrite").save(partition_1)
..
df.write.partitionBy("column_7").format("delta").mode("overwrite").save(partition7)

因此,我想看看哪种分区策略会带来更好的结果:具有高基数的列、具有低基数的列或介于两者之间的列。 令我惊讶的是,这并没有产生任何影响,因为它几乎花费了所有时间,只是相差几分钟,但所有时间都为 + 3 小时。

为什么我失败了?分区没有优势吗?

最佳答案

当您使用 Delta(Databricks 或 OSS Delta 1.2.x,更好的 2.0)时,通常您可能根本不需要使用分区,原因如下(不适用于 Parquet 或其他文件格式):

对 Delta 湖表使用分区的经验法则如下:

  • 在有利于查询时使用它,尤其是当您对表执行 MERGE 时,因为它可以避免并行事务之间的冲突
  • 当它有助于删除旧数据时(例如按日期分区)
  • 当它真正有益于您的查询时。例如,您有每个国家/地区的数据,并且大多数查询将使用国家/地区作为条件的一部分。或者例如,当您按日期分区,并根据时间查询数据时...

在所有情况下,不要对高基数列(数百个值)和分区列太多使用分区,因为在大多数情况下,这会导致创建读取效率较低的小文件(每个文件单独访问) ),加上它会增加驱动程序的负载,因为它需要为每个文件保留元数据。

关于delta-lake - 如何有效地对 Delta 表进行分区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73094038/

相关文章:

apache-spark - Delta Lake 独立于 Apache Spark?

azure - 优化时间戳范围查询的 Delta Lake 分区

databricks - 如何在Databricks中重命名列

PySpark Delta Table - 生成符号链接(symbolic link) [java.lang.NoSuchMethodError]

delta-lake - 内部部署的三角洲湖

databricks - Delta Lake 存储层 - 概念

apache-spark - 三角洲湖上的 hive 表

scala - 如何修复 sbt 项目中的 "origin location must be absolute"错误(使用 Spark 2.4.5 和 DeltaLake 0.6.1)?

apache-spark - 通过提供表名称而不是表路径将 Spark Dataframe 写入现有的增量表