PySpark写入Redshift时postActions查询优化及改进方案问询
优化方案
1. 可读性提升:替换为更易懂的IN子查询写法
你当前使用的USING是Redshift原生的多表关联删除语法,如果你觉得逻辑难理解,可以替换为逻辑更直白的IN子查询实现,完全满足「删除master表中所有updatekey存在于staging表的行」的需求:
DELETE FROM {mastertable} WHERE {updatekey} IN (SELECT DISTINCT {updatekey} FROM {staging});
这种写法不需要掌握多表关联删除的特殊语法规则,普通SQL使用者都能一眼看懂逻辑。
2. 性能问题解决方案
你遇到的性能问题大概率是临时生成的staging表没有合理的键配置导致的,可通过以下调整解决:
- 新增
preactions配置,提前创建和主表结构、键配置完全一致的staging表,避免自动创建的staging表没有sortkey、distkey,导致关联匹配时触发全表扫描 - 子查询中增加
DISTINCT去重,减少匹配时的比对行数 - 如果staging表数据量较大,可以在写入后先对staging表执行
ANALYZE更新统计信息,提升删除操作的执行计划效率
优化后的完整代码
def updatemaster_table(mastertable, dataframe, updatekey): staging = mastertable + '_staging' # 写入前先删除旧临时表,创建和主表结构、键配置完全一致的新临时表 preActions = f""" DROP TABLE IF EXISTS {staging}; CREATE TABLE {staging} (LIKE {mastertable}); """ postActions = f""" DELETE FROM {mastertable} WHERE {updatekey} IN (SELECT DISTINCT {updatekey} FROM {staging}); DROP TABLE IF EXISTS {staging}; """ dataframe.write \ .format("com.databricks.spark.redshift") \ .option("url", REDSHIFT_JDBC_URL) \ .option("dbtable", staging) \ .option("extracopyoptions", EXTRACOPYOPTIONS) \ .option("preactions", preActions) \ .option("postactions", postActions) \ .option("forward_spark_s3_credentials", "true") \ .option("tempdir", "s3a://" + S3_BUCKET + "/tempdir") \ .mode("append") \ .save()
内容的提问来源于stack exchange,提问作者asha k
相关产品推荐
相关产品推荐

