首页 > 解决方案 > 在火花中加入多个 jdbc 连接表的最佳方法是什么?

问题描述

我正在尝试将查询迁移到 pyspark 并需要在其中加入多个表。所有有问题的表都在 Redshift 中,我正在使用 jdbc 连接器与它们交谈。

我的问题是如何在不读取太多数据(即加载表和键连接)的情况下以最佳方式进行这些连接,并且不公然使用:

spark.sql("""join table1 on x=y join table2 on y=z""")

有没有办法将查询下推到 Redshift 但仍然使用 Spark df API 来编写逻辑并利用 spark 上下文中的 df 而不将它们保存到 Redshift 仅用于连接?

标签: apache-sparkpysparkamazon-redshiftpyspark-sqlpyspark-dataframes

解决方案


请找出接下来要考虑的几点:

  • 仅当您的 Spark 代码中指定了任何过滤器时,连接器才会下推指定的过滤器,例如select * from tbl where id > 10000. 您可以自己确认,只需检查负责的 Scala代码即可。这里也是相应的测试,它准确地证明了这一点。该测试test("buildWhereClause with multiple filters")尝试验证变量expectedWhereClause是否等于whereClause连接器生成的变量。生成的 where 子句应该是:
"""
        |WHERE "test_bool" = true
        |AND "test_string" = \'Unicode是樂趣\'
        |AND "test_double" > 1000.0
        |AND "test_double" < 1.7976931348623157E308
        |AND "test_float" >= 1.0
        |AND "test_int" <= 43
        |AND "test_int" IS NOT NULL
        |AND "test_int" IS NULL
      """

这是从Spark-filters上面指定的。

  • 驱动也支持column filtering。这意味着它将通过将有效列下推到红移来仅加载所需的列。您可以再次从相应的 Scala test("DefaultSource 支持简单列过滤")test("query with pruned and filtered scans")中验证这一点。

  • 尽管在您的情况下,您没有在联接查询中指定任何过滤器,因此 Spark 无法利用前两个优化。如果您知道此类过滤器,请随时应用它们。

  • 最后但同样重要的是,正如 Salim 已经提到的,可以在此处找到用于 redshift 的官方 Spark 连接器。Spark 连接器构建在Amazon Redshift JDBC 驱动程序之上,因此它将尝试按照连接器代码中指定的方式使用它。


推荐阅读