无主键列的 Spark jdbc 读取性能调优
Posted
技术标签:
【中文标题】无主键列的 Spark jdbc 读取性能调优【英文标题】:Spark jdbc read performance tuning with no primary key column 【发布时间】:2019-09-26 08:23:17 【问题描述】:我正在运行一个 spark 分析应用程序并使用 spark jdbc
直接读取 MSSQL Server 表(整个表)。该表有超过 30M 的记录,但没有任何主键列或整数列。由于表格没有这样的列,我无法使用partitionColumn
,因此阅读表格需要太多时间。
val datasource = spark.read.format("jdbc")
.option("url", "jdbc:sqlserver://host:1433;database=mydb")
.option("driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver")
.option("dbtable", "dbo.table")
.option("user", "myuser")
.option("password", "password")
.option("useSSL", "false").load()
在这种情况下,有什么方法可以提高性能,并在从关系数据库源(源可能是 Oracle、MSSQL Server、mysql、DB2)读取数据时使用并行性。
【问题讨论】:
太模糊了。加入?只想要增量或所有数据 oer 表? How to optimize partitioning when migrating data from JDBC source?的可能重复 我已经更新了这个问题。如果我们没有任何 CLI 列,我肯定必须阅读整个表格。 @user10958683 - 不是真的,我的表没有任何主键或更改数据标识符列或整数列。 使用 sqoop 并进行一些分析以确定合适的拆分列 【参考方案1】:唯一的方法是编写一个返回分区数据的查询并将partitionColumn指定到生成的新列中,但我不知道这是否真的可以加速您的摄取。
以伪sql代码为例:
val myReadQuery = SELECT *,(rowid %5) as part from table
之后
val datasource = spark.read.format("jdbc")
.option("url", "jdbc:sqlserver://host:1433;database=mydb")
.option("driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver")
.option("dbtable", s"($myReadQuery) as t")
.option("user", "myuser")
.option("password", "password")
.option("useSSL", "false").
.option("numPartitions", 5)
.option("partitionColumn", "part")
.option("lowerBound", 1)
.option("upperBound", 5).load()
但是我已经说过了,我不确定这是否可以改善您的摄取。 因为这会导致这样的 5 个并行查询:
SELECT * from (select *, (rowid%5) as part from table) where part >= 0 and part < 1
SELECT * from (select *, (rowid%5) as part from table) where part >= 1 and part < 2
SELECT * from (select *, (rowid%5) as part from table) where part >= 2 and part < 3
SELECT * from (select *, (rowid%5) as part from table) where part >= 3 and part < 4
SELECT * from (select *, (rowid%5) as part from table) where part >= 4 and part < 5
但我认为,如果在你的表中有一个索引,你可以使用索引提取一个整数,通过 mod 操作可以拆分读取操作,同时可以加快读取查询。
【讨论】:
我相信,partitionColumn
应该是主键列或整数列。你能解释一下numPartitions
、numPartitions
、lowerBound
和upperBound
在我的例子中的用法吗?
是的。 PartitionColumn 必须是整数类型,但您可以创建一个可以用作分区器的整数字段。 numPartitions 是读取分区的编号,lowerBound 和 upperBound 用于指定 partitionColumn 的最大值和最小值,因此 spark,内部可以像我之前写的那样构建查询并并行运行查询而不会重复以上是关于无主键列的 Spark jdbc 读取性能调优的主要内容,如果未能解决你的问题,请参考以下文章