Apache spark 在不同的保存模式下,saveAsTable和insertInto之间有什么区别?
我正试图在Apache spark 在不同的保存模式下,saveAsTable和insertInto之间有什么区别?,apache-spark,Apache Spark,我正试图在覆盖模式下(对于我的应用程序是必需的)将数据帧写入Hive表(在S3上),并需要在DataFrameWriter的两种方法(Spark/Scala)之间做出选择。从中可以看出,df.write.saveAsTable与df.write.insertInto在以下方面有所不同: saveAsTable使用基于列名的分辨率,而insertInto使用基于位置的分辨率 在追加模式下,saveAsTable更关注现有表的底层架构,以确定某些分辨率 总的来说,它给我的印象是,saveAsTa
覆盖
模式下(对于我的应用程序是必需的)将数据帧
写入Hive
表(在S3
上),并需要在DataFrameWriter的两种方法(Spark/Scala)之间做出选择。从中可以看出,df.write.saveAsTable
与df.write.insertInto
在以下方面有所不同:
使用基于列名的分辨率,而saveAsTable
使用基于位置的分辨率insertInto
- 在追加模式下,
更关注现有表的底层架构,以确定某些分辨率saveAsTable
saveAsTable
只是insertInto
的一个更智能的版本。或者,根据用例,您可能更喜欢insertInto
但是,这些方法中的每一种是否都有自己的一些警告,比如在saveAsTable
的情况下会有性能损失(因为它包含了更多的功能)?除了文件中所述(不是很清楚)之外,他们的行为是否还有其他差异
编辑-1 有关插入的
文档说明了这一点
将数据框的内容插入到指定的表中
对于saveAsTable
如果表已经存在,则此函数的行为
取决于模式函数指定的保存模式
现在我可以列出我的疑问了
insertInto
是否总是希望该表存在
SaveMode
s是否对插入有任何影响
- 如果上述答案是肯定的,那么
- 如果表已经存在,
saveAsTable
与SaveMode.Append
和insertInto
之间有什么区别
- 使用
SaveMode.OverwriteinsertInto
是否有意义
免责声明一段时间以来,我一直在探索插入
,尽管我远不是这方面的专家,但为了更好地分享这些发现
insertInto
是否总是希望该表存在
(根据表名和数据库)
此外,并非所有表都可以插入,即(永久)表、临时视图或临时全局视图都可以,但不是:
带扣的桌子
基于RDD的表
保存模式对insertInto有影响吗
(这也是我最近的问题!)
是的,但只是。在您考虑insertInto
之后,其他3种保存模式没有多大意义(因为它只是插入一个数据集)
如果表已经存在,则saveAsTable与SaveMode.Append和insertInto之间有什么区别
这是一个很好的问题!我想说没有,但让我们看一个例子(希望这能证明一些事情)
使用SaveMode.Overwrite插入有意义吗
我想是的,因为它非常关注SaveMode.Overwrite
。它只是重新创建目标表
spark.range(3).write.mode("overwrite").insertInto("my_table")
scala> spark.table("my_table").show
+---+
| id|
+---+
| 1|
| 0|
| 2|
+---+
Seq(100, 200, 300).toDF.write.mode("overwrite").insertInto("my_table")
scala> spark.table("my_table").show
+---+
| id|
+---+
|200|
|100|
|300|
+---+
另一个重要点,我在将数据插入到SIFB2.xx:/P>>现有的HiVE动态分区表时要考虑
df.write.mode("append").insertInto("dbName"."tableName")
上面的命令将在本质上映射“df”中的数据,并且只将新分区附加到现有表中
希望如此,它在决定何时使用“insertInto”时又增加了一点 我最近开始将我的Hive脚本转换为Spark,我还在学习
我注意到saveAsTable和insertInto有一个重要的行为,但尚未讨论
saveAsTable(“schema.table”)删除现有表“schema.table”,并基于“df”模式重新创建新表。现有表的模式变得不相关,不必与df匹配。我被这种行为咬了一口,因为我现有的桌子是ORC,而新创建的桌子是拼花地板(火花默认)
insertInto(“schema.table”)不会删除现有表,并希望现有表的架构与“df”的架构匹配
我使用这两个选项检查了表的创建时间,并重申了该行为
原始表格存储为ORC-Wed Sep 04 21:27:33 GMT 2019
保存稳定后(存储更改为拼花)-2019年9月4日星期三21:56:23 GMT(创建时间更改)
放弃并重新创建origina表(ORC)-Wed Sep 04 21:57:38 GMT 2019
插入后(仍然是ORC)Wed Sep 04 21:57:38 GMT 2019(创建时间未更改)我想指出SPARK中的SaveAsTable
和insertInto
之间的主要区别
在分区表中,overwrite
SaveMode在SaveAsTable
和insertInto
情况下的工作方式不同
考虑下面的例子,我使用SaveAsTable
方法创建分区表
hive> CREATE TABLE `db.companies_table`(`company` string) PARTITIONED BY ( `id` date);
OK
Time taken: 0.094 seconds
现在我添加了两个新行和两个新分区值
scala> val companiesDF = Seq(("2020-01-03", "Company1"), ("2020-01-04", "Company2")).toDF("id", "company")
scala> companiesDF.write.mode(SaveMode.Append).partitionBy("id").saveAsTable(targetTable)
scala>spark.sql("select * from db.companies_table").show()
+--------+----------+
| company| id|
+--------+----------+
|Company1|2020-01-01|
|Company2|2020-01-02|
|Company1|2020-01-03|
|Company2|2020-01-04|
+--------+----------+
如您所见,表中添加了两个新行
现在让我们假设我想要覆盖分区2020-01-02数据
scala> val companiesDF = Seq(("2020-01-02", "Company5")).toDF("id", "company")
scala>companiesDF.write.mode(SaveMode.Overwrite).partitionBy("id").saveAsTable(targetTable)
根据我们的逻辑,只有分区2020-01-02应该被覆盖,但是SaveAsTable
的情况不同。它将覆盖enter表,如下所示
scala> spark.sql("select * from db.companies_table").show()
+-------+----------+
|company| id|
+-------+----------+
|Company5|2020-01-02|
+-------+----------+
因此,如果我们只想使用SaveAsTable
覆盖表中的某些分区,这是不可能的
有关更多详细信息,请参阅此链接。
我遇到的所有QAs/链接都抱怨Spark本质上覆盖了所有分区(在覆盖模式下),需要一些技巧来绕过这个相当抑制性的缺点Hi Jacek,你知道为什么吗
scala> val companiesDF = Seq(("2020-01-02", "Company5")).toDF("id", "company")
scala>companiesDF.write.mode(SaveMode.Overwrite).partitionBy("id").saveAsTable(targetTable)
scala> spark.sql("select * from db.companies_table").show()
+-------+----------+
|company| id|
+-------+----------+
|Company5|2020-01-02|
+-------+----------+