Apache spark partitionColumn、lowerBound、upperBound和numPartitions参数的含义是什么?
在Spark中通过JDBC连接从SQL Server获取数据时,我发现我可以设置一些并行化参数,如Apache spark partitionColumn、lowerBound、upperBound和numPartitions参数的含义是什么?,apache-spark,jdbc,apache-spark-sql,Apache Spark,Jdbc,Apache Spark Sql,在Spark中通过JDBC连接从SQL Server获取数据时,我发现我可以设置一些并行化参数,如partitionColumn、lowerBound、upperBound和numPartitions。我经历过,但无法理解 谁能给我解释一下这些参数的含义吗?很简单: partitionColumn是一个用于确定分区的列 lowerBound和upperBound确定要获取的值的范围。完整数据集将使用与以下查询对应的行: SELECT * FROM table WHERE partitionCo
partitionColumn
、lowerBound
、upperBound
和numPartitions
。我经历过,但无法理解
谁能给我解释一下这些参数的含义吗?很简单:
是一个用于确定分区的列partitionColumn
和lowerBound
确定要获取的值的范围。完整数据集将使用与以下查询对应的行:upperBound
SELECT * FROM table WHERE partitionColumn BETWEEN lowerBound AND upperBound
确定要创建的分区数。介于numPartitions
和lowerBound
之间的范围分为upperBound
,每个部分的步幅等于:numPartitions
例如,如果:upperBound / numPartitions - lowerBound / numPartitions
:0lowerBound
:1000上限
:10numPartitions
SELECT * FROM table WHERE partitionColumn < 100 or partitionColumn is null SELECT * FROM table WHERE partitionColumn >= 100 AND <200 SELECT * FROM table WHERE partitionColumn >= 200 AND <300 SELECT * FROM table WHERE partitionColumn >= 300 AND <400 ... SELECT * FROM table WHERE partitionColumn >= 400
从partitionColumn介于0和100之间的表中选择*
从partitionColumn位于100和200之间的表中选择*
…
从分区列在900和1000之间的表中选择*
下界
之前的数据和上界
之后的数据)。由于下限为0,因此示例中的值不清楚
完整清单应为:
SELECT * FROM table WHERE partitionColumn < 100
SELECT * FROM table WHERE partitionColumn BETWEEN 0 AND 100
SELECT * FROM table WHERE partitionColumn BETWEEN 100 AND 200
只想补充一下验证过的答案,因为 如果没有它们,您将丢失一些数据具有误导性 根据文件, 请注意,lowerBound和upperBound仅用于确定分区步长,而不是用于筛选表中的行。因此,表中的所有行都将被分区并返回。此选项仅适用于阅读。 也就是说,假设您的表有1100行,您可以指定
lowerBound
0
上限
1000和
numPartitions
:10
,您不会丢失1000到1100行。您只会看到一些分区的行数比预期的多。(步长值为100)。创建分区不会由于过滤而导致数据丢失。
上限
,下限
以及numPartitions
仅定义了如何创建分区。上限
和下限
不定义要获取的partitionColumn值的范围(筛选器)
For a given input of lowerBound (l), upperBound (u) and numPartitions (n)
The partitions are created as follows:
stride, s= (u-l)/n
**SELECT * FROM table WHERE partitionColumn < l+s or partitionColumn is null**
SELECT * FROM table WHERE partitionColumn >= l+s AND <2s
SELECT * FROM table WHERE partitionColumn >= l+2s AND <3s
...
**SELECT * FROM table WHERE partitionColumn >= l+(n-1)s**
根据
partitionColumn
的实际值范围,每个分区的结果大小将有所不同。对于JdbcRDD(),这是100%准确的。特别是,如果将上限设置得太低,则一个执行器的工作量将远远超过其他执行器,并且可能会耗尽内存。快速问题:哪种类型的列最适合PartitionBy?序列UUID?包含中间运算符:包括开始值和结束值。所以上面的sql将查询重复的数据,对吗?答案并不准确,因为在某些数据库中,BETWEEN
包含下限和上限。实际实现使用=
和这个答案是否假设分区列的值从1到1000递增,例如?否则就没有意义了。我有一个由Netezza数据库分配的partitionColumn
,它是一个大数字234235000
到23424399
。如果upperBound
指的是元素的数量,而不是partitionColumn中的值,那么这个答案对我来说没有意义。请参阅Andrea的答案。第一个和最后一个SELECT在他的答案中是正确的,但在这个答案中不是这样的:注意,lowerBound和upperBound只是用来决定分区跨距,而不是用来过滤表中的行。因此,表中的所有行都将被分区并返回。此选项仅适用于读取。这意味着将获取整个表,而不仅仅是下限和上限之间的部分。答案并不准确,因为在某些数据库中,between
包含下限和上限。实际实现使用=
和这是一个完全错误的答案,这意味着上限和下限值过滤正在读取的数据集。您知道Spark对剩余的100行做了什么吗?例如,这是否意味着您的10个分区将有110行?您能否澄清关于partitionColumn
中的值的假设?如果没有唯一的整数ROWID,比如1,2,3,4,…,我无法理解这是如何工作的。
SELECT * FROM table WHERE partitionColumn < 100 or partitionColumn is null
SELECT * FROM table WHERE partitionColumn >= 100 AND <200
SELECT * FROM table WHERE partitionColumn >= 200 AND <300
SELECT * FROM table WHERE partitionColumn >= 300 AND <400
...
SELECT * FROM table WHERE partitionColumn >= 400