簡體   English   中英

如何在 Spark 中獲取 hive 表的分區信息

[英]how to get the partitions info of hive table in Spark

我想像這樣通過 Spark 執行 SQL。

sparkSession.sql("select * from table")

但我想在執行避免全掃描之前對表進行分區檢查。

如果表是分區表,我的程序會強制用戶添加分區過濾器。 如果沒有,可以運行。

所以我的問題是如何知道一個表是否是一個分區表? 我的想法是從 Metastore 中讀取信息。 但是如何獲取 Metastore 是我遇到的另一個問題。 有人可以幫忙嗎?

假設您的真正目標是限制無限查詢的執行,我認為獲取查詢的執行計划並查看其FileScan / HiveTableScan葉節點以查看是否正在應用任何分區過濾器會更容易。 順便說一下,對於分區表,查詢實際要掃描的分區數也會顯示出來。 所以,這樣的事情應該做:

scala> val df_unbound = spark.sql("select * from hottab")
df_unbound: org.apache.spark.sql.DataFrame = [id: int, descr: string ... 1 more field]

scala> val plan1 = df_unbound.queryExecution.executedPlan.toString
plan1: String =
"*(1) FileScan parquet default.hottab[id#0,descr#1,loaddate#2] Batched: true, Format: Parquet, 
Location: CatalogFileIndex[hdfs://ns1/user/hive/warehouse/hottab], 
PartitionCount: 365, PartitionFilters: [],
PushedFilters: [], ReadSchema: struct<id:int,descr:string>
"

scala> val df_filtered = spark.sql("select * from hottab where loaddate='2019-07-31'")
df_filtered: org.apache.spark.sql.DataFrame = [id: int, descr: string ... 1 more field]

scala> val plan2 = df_filtered.queryExecution.executedPlan.toString
plan2: String =
"*(1) FileScan parquet default.hottab[id#17,descr#18,loaddate#19] Batched: true, Format: Parquet, 
Location: PrunedInMemoryFileIndex[hdfs://ns1/user/hive/warehouse/hottab/loaddate=2019-07-31], 
PartitionCount: 1, PartitionFilters: [isnotnull(loaddate#19), (loaddate#19 = 2019-07-31)], 
PushedFilters: [], ReadSchema: struct<id:int,descr:string>
"

這樣,您也不必處理 SQL 解析來從查詢中查找表名,也不必自己查詢元存儲。

作為獎勵,除了分區修剪之外,您還可以查看是否發生“常規”過濾器下推(對於支持它的存儲格式)。

您可以使用 Scala 的Try類並在所需的表上執行show partitions

val numPartitions = Try(spark.sql("show partitions database.table").count) match {
    case Success(v) => v
    case Failure(e) => -1
}

稍后您可以檢查numPartitions 如果值為-1則表未分區。

  val listPartitions = spark.sessionState.catalog.listPartitionNames(TableIdentifier("table_name", Some("db name")))
  listPartitions: Seq[String] = ArrayBuffer(partition1=value1, ... )  // partition table
  listPartitions: Seq[String] = ArrayBuffer() // not partition table

我知道這已經晚了,但這可能會對某人有所幫助

spark.sql("describe detail database.table").select("partitionColumns").show(false)

這是在數組中給出具有分區列的行

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM