在将数据帧存储在增量表中时,为我的数据帧寻找有效的分区策略。
我当前的数据帧 1.5000.000 rowa 将数据从数据帧移动到增量表需要 3.5 小时。
为了寻找一种更有效的方法来完成此写作,我决定尝试表中的不同列作为分区列。我搜索了列的基数并选择了以下列。
column1 = 有 3 个不同的值
column2 = 有 7 个不同的值
第 3 列 = 有 26 个不同的值
第 4 列 = 有 73 个不同的值
第 5 列 = 有 143 个不同的值
第 6 列 = 有 246 个不同的值
第 7 列 = 有 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 或其他文件格式):
- 达美支持数据跳跃 https://docs.databricks.com/delta/optimizations/file-mgmt.html#data-skipping允许只读取必要的文件,当您与优化 ZORDER BY https://docs.databricks.com/delta/optimizations/file-mgmt.html#z-ordering-multi-dimensional-clustering这将使相关数据彼此更加接近。
-
布隆过滤器 https://docs.databricks.com/delta/optimizations/bloom-filters.html允许更精细地跳过文件。
使用 Delta Lake 表分区的经验规则如下:
- 当它有利于查询时使用它,特别是当您对表执行 MERGE 时,因为它可以避免并行事务之间的冲突
- 当它有助于删除旧数据时(例如按日期分区)
- 当它真正有利于您的查询时。例如,您有每个国家/地区的数据,并且大多数查询将使用国家/地区作为条件的一部分。或者例如,当您按日期分区并根据时间查询数据时......
在所有情况下,不要对高基数列(数百个值)和具有太多分区列使用分区,因为在大多数情况下,这会导致创建读取效率较低的小文件(每个文件单独访问),另外它会增加驱动程序的负载,因为它需要保留每个文件的元数据。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)