我有一个Hive数据库,示例中的所有表都是Parquet格式的Hive表。
假设这是我的应用程序中的前两个 Spark SQL查询(为方便起见,简化了模式):
1) val df1 = spark.sql("select * from T1 where T1.col1 = 'a'")
2) val df2 = spark.sql("select * from T1 where T1.col2 = 'b'")
执行动作时,我会根据顺序得到不同的时间:
df1.count()
Time taken: 18062 ms
df2.count()
Time taken: 7037 ms
(在另一个Spark应用程序/ shell上)
df2.count()
Time taken: 20330 ms
df1.count()
Time taken: 4131 ms
我试图解释的一种方法是,第二个数据帧可以利用前一次执行留下的内存中信息,因为两个数据帧都访问同一张表。
但是,有一天,我在两个不同的表T1和T2 上尝试了类似的操作:
1) val df3 = spark.sql("select * from T1 where T1.col1 = 'c'")
2) val df4 = spark.sql("select * from T2 where T2.col1 = 'd'")
并得到:
df3.count()
Time taken: 18062 ms
df4.count()
Time taken: 712 ms
(在另一个Spark应用程序/ shell上)
df4.count()
Time taken: 11447 ms
df3.count()
Time taken: 15042 ms
因此,似乎最后执行的数据帧总是比第一次执行的时间要长。
1)这怎么可能,尤其是在访问两个不同表的情况下?我该怎么解释?
2)如果这不是由于内存中的数据重用引起的,是否有办法摆脱第一次执行的开销?
3)如果我必须报告执行时间,那么在第一次或第二次执行时报告时间会更公平吗?