在pysparkDataframe中读取hive分区orc表时逻辑和物理计划的工作原理

tjjdgumg  于 2021-06-27  发布在  Hive
关注(0)|答案(1)|浏览(380)

我创建了一个sparkDataframe,从hdfs位置读取csv。

  1. emp_df = spark.read.format("com.databricks.spark.csv") \
  2. .option("mode", "DROPMALFORMED") \
  3. .option("header", "true") \
  4. .option("inferschema", "true") \
  5. .option("delimiter", ",").load(PATH_TO_FILE)

并使用partitionby方法将此Dataframe保存为配置单元分区orc表

  1. emp_df.repartition(5, 'emp_id').write.format('orc').partitionBy("emp_id").saveAsTable("UDB.temptable")

当我按照下面的方法阅读此表时,如果我查看逻辑和物理计划,它似乎已经使用分区键列完美地过滤了数据:

  1. emp_df_1 = spark.sql("select * from UDB.temptable where emp_id ='6'")
  2. emp_df_1.explain(True)
  3. ***************************************************************************
  4. == Parsed Logical Plan ==
  5. 'Project [*]
  6. +- 'Filter ('emp_id = 6)
  7. +- 'UnresolvedRelation `UDB`.`temptable`
  8. == Analyzed Logical Plan ==
  9. emp_name: string, emp_city: string, emp_salary: int, emp_id: int
  10. Project [emp_name#7399, emp_city#7400, emp_salary#7401, emp_id#7402]
  11. +- Filter (emp_id#7402 = cast(6 as int))
  12. +- SubqueryAlias temptable
  13. +- Relation[emp_name#7399,emp_city#7400,emp_salary#7401,emp_id#7402] orc
  14. == Optimized Logical Plan ==
  15. Filter (isnotnull(emp_id#7402) && (emp_id#7402 = 6))
  16. +- Relation[emp_name#7399,emp_city#7400,emp_salary#7401,emp_id#7402] orc
  17. == Physical Plan ==
  18. * (1) FileScan orc udb.temptable[emp_name#7399,emp_city#7400,emp_salary#7401,emp_id#7402] Batched: true, Format: ORC, Location: PrunedInMemoryFileIndex[hdfs://pathlocation/database/udb....,
  19. PartitionCount: 1, PartitionFilters: [isnotnull(emp_id#7402), (emp_id#7402 = 6)], PushedFilters: [], ReadSchema: struct<emp_name:string,emp_city:string,emp_salary:int>
  20. ***************************************************************************

然而,如果我通过绝对hdfs路径位置读取此Dataframe,则似乎无法使用分区键列过滤数据:

  1. emp_df_2 = spark.read.format("orc").load("hdfs://pathlocation/database/udb.db/temptable/emp_id=6")
  2. emp_df_2.explain(True)
  3. ******************************************************************************
  4. == Parsed Logical Plan ==
  5. Relation[emp_name#7411,emp_city#7412,emp_salary#7413] orc
  6. == Analyzed Logical Plan ==
  7. emp_name: string, emp_city: string, emp_salary: int
  8. Relation[emp_name#7411,emp_city#7412,emp_salary#7413] orc
  9. == Optimized Logical Plan ==
  10. Relation[emp_name#7411,emp_city#7412,emp_salary#7413] orc
  11. == Physical Plan ==
  12. * (1) FileScan orc [emp_name#7411,emp_city#7412,emp_salary#7413] Batched: true, Format: ORC, Location: InMemoryFileIndex[hdfs://pathlocation/data/database/udb.db/tem...,
  13. PartitionFilters: [], PushedFilters: [], ReadSchema: struct<emp_name:string,emp_city:string,emp_salary:int>
  14. ********************************************************************************

你能帮我理解这两种情况下的逻辑和物理计划吗?

de90aj5v

de90aj5v1#

在第二个示例中,分区位置已经包含在hdfs路径中。您仍然可以将父目录作为路径,并使用分区和以下代码:

  1. full_dataset_df = spark.read.format("orc") \
  2. .load("hdfs://pathlocation/database/udb.db/temptable")
  3. one_partition_df = full_dataset_df.where(full_dataset_df.emp_id == 6)

值得一提的是,无论您使用这3种方法中的哪种,数据处理性能都是相同的。

相关问题