postgresql—对没有整数主键列的表使用spark并行地从postgres读取数据

gupuwyp2  于 2021-05-17  发布在  Spark
关注(0)|答案(1)|浏览(531)

我正在从postgres表中读取数据,该表包含特定季度的1.02亿条记录。该表包含多个季度的数据。现在我正在通过sparkjdbc连接器读取数据,获取数据花费了太多时间。当我在Dataframe上执行操作(如count())时,加载数据几乎需要15-20分钟。数据在单个任务上加载或处理,因此我希望并行处理/读取数据。
我使用以下代码获取数据并创建连接:

import java.util.Properties
//function to get the connection properties
def getDbConnectionProperties(environment:Int) : Properties = {

val connectionProps = new Properties()
connectionProps.setProperty("user", user)
 connectionProps.setProperty("password", password )
connectionProps.setProperty("driver", "org.postgresql.Driver")
connectionProps.setProperty("stringtype", "unspecified")  //to save the records with the UUID type which are string in dataframe schema
connectionProps
}
val jdbcurl= "jdbc:postgresql://xxxxx : 5432/test"
val connectionString = jdbcurl;
val connectionProps = getDbConnectionProperties(environment)
val readPGSqlData =  spark.read.jdbc(connectionString,_:String,connectionProps)
val query = s"""(select Column_names from TableName where Period= "2020Q1") a"""
val PGExistingRecords = readPGSqlData(existingRecordsQuery)
PGExistingRecords.count()  //takes 15-20 minutes

我知道如果您指定分区列并指定下限和上限,并且分区列需要是整数,我们可以并行读取数据,但在我的示例中,没有任何整数类型的列。主键的类型也是guid。
任何能让我更快地读取数据或在并行任务中读取数据的方法都会对我有所帮助。任何关于我是否可以使用任何第三方的功能或任何方式,我可以这样做,使用本机jdbc连接器的建议。

zmeyuzjn

zmeyuzjn1#

对于guid类型,可以按第一个字符拆分数据:

val tableData =
  List("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")
    .map{prefix =>
      val sql = "(select * from table_name where guid_col like '%s%s') t".format(prefix, "%")
      spark.read.jdbc(url = url, table = sql, properties = connectionProps)
    }
    .reduce(_.union(_))

性能注意:为了获得最佳性能,您应该在guid列或非聚集列上有一个聚集索引,其中包括所有其他列。因此,所有读取线程都将使用索引查找和顺序i/o,否则会导致对每个线程进行全表扫描或随机i/o,这可能比在一个线程中读取表慢。

相关问题