spark sql 查看分区_apache-spark – 使用日期范围对分区数据进行Spark SQL查询

本文探讨了如何在Apache Spark中利用Spark SQL高效地查询日期范围内的分区数据。介绍了全量扫描和部分扫描两种方法,并提供了具体代码示例,包括使用外部分区表和联合查询来优化查询性能。
摘要由CSDN通过智能技术生成

如果您必须坚持这种分区策略,答案取决于您是否愿意承担分区发现成本.

如果您愿意让Spark发现所有分区,只需要发生一次(直到您添加新文件),您可以加载基本路径,然后使用分区列进行过滤.

如果您不希望Spark发现所有分区,例如,因为您有数百万个文件,唯一有效的通用解决方案是将您要查询的间隔分成几个子区间,您可以使用@ r0bb23的方法轻松查询这些区间然后联合在一起.

如果您想要上述两种情况中的最佳情况并且您具有稳定的架构,则可以通过定义外部分区表来在Metastore中注册分区.如果您希望您的架构随着Metastore管理的表格在此时管理架构演变而发展,那么请不要这样做.

例如,要在2017-10-06和2017-11-03之间进行查询,您需要执行以下操作:

// With full discovery

spark.read.parquet("hdfs:///basepath")

.where('Year === 2017 && (

('Month === 10 && 'Day >= 6') || ('Month === 11 && 'Day <= 3')

))

// With partial discovery

val df1 = spark.read.option("basePath", "hdfs:///basepath/")

.parquet("hdfs:///basepath/Year=2017/Month=10/Day={0[6-9], [1-3][0-9]}/*/")

val df2 = spark.read.option("basePath", "hdfs:///basepath/")

.parquet("hdfs:///basepath/Year=2017/Month=11/Day={0[1-3]}/*/")

val df = df1.union(df2)

为此编写通用代码当然是可能的,但我没有遇到过.更好的方法是按照我对问题所做的评论中概述的方式进行分区.如果您的表使用/basepath/ts=yyyymmddhhmm/*.parquet之类的内容进行分区,那么答案很简单:

为什么值得增加小时和时间的原因分钟是您可以编写处理间隔的通用代码,无论您是按周,日,小时还是每15分钟划分数据.实际上,您甚至可以在同一个表中管理具有不同粒度的数据,例如,较旧的数据在较高级别聚合以减少需要发现的分区总数.spark.read.parquet("hdfs:///basepath")

.where('ts >= 201710// With full discovery

spark.read.parquet("hdfs:///basepath")

.where('Year === 2017 && (

('Month === 10 && 'Day >= 6') || ('Month === 11 && 'Day <= 3')

))

// With partial discovery

val df1 = spark.read.option("basePath", "hdfs:///basepath/")

.parquet("hdfs:///basepath/Year=2017/Month=10/Day={0[6-9], [1-3][0-9]}/*/")

val df2 = spark.read.option("basePath", "hdfs:///basepath/")

.parquet("hdfs:///basepath/Year=2017/Month=11/Day={0[1-3]}/*/")

val df = df1.union(df2)// With full discovery

spark.read.parquet("hdfs:///basepath")

.where('Year === 2017 && (

('Month === 10 && 'Day >= 6') || ('Month === 11 && 'Day <= 3')

))

// With partial discovery

val df1 = spark.read.option("basePath", "hdfs:///basepath/")

.parquet("hdfs:///basepath/Year=2017/Month=10/Day={0[6-9], [1-3][0-9]}/*/")

val df2 = spark.read.option("basePath", "hdfs:///basepath/")

.parquet("hdfs:///basepath/Year=2017/Month=11/Day={0[1-3]}/*/")

val df = df1.union(df2)0L && 'ts <= 201711030000L)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值