我在AWS S3上有一个CSV文件和一个JSON文件(每个文件都有500万行/记录)。它们包含完全相同的数据,只是格式不同。
在有10个任务节点的EMR集群上,我启动了Spark (10个执行器,40个执行器核心),并创建了两个DataFrames:一个针对CSV,一个针对JSON。
对构建在JSON文件上的DF的查询运行速度比对CSV构建的DF的类似查询快2-3倍。我没有发现任何关于跨存储文件格式的性能差异的信息。
有没有人知道为什么对JSON上的DF的查询比CSV上的DF运行得更快?
在下创建数据仓库的代码
针对JSON文件创建DF:
val hc_json = new org.apache.spark.sql.hive.HiveContext(sc)
val path_json = "s3://<mybucket>/<myjsonfile>.json"
val df_json = hc_json.read.json(path_json)
df_json.registerTempTable("table_json")
hc_json.sql("Select count(*) from table_json").collect()针对CSV文件创建DF:
(我在使用以下参数启动火花-csv包时导入了该软件包:--packages com.databricks:S火花-csv_2.11:1.2.0)
val hc_csv = new org.apache.spark.sql.hive.HiveContext(sc)
val path_csv = "s3://<mybucket>/<mycsvfile>.csv"
val df_csv = hc_csv.load("com.databricks.spark.csv", Map("path" -> path,"header"->"false"))
df_csv.registerTempTable("table_csv")
hc_csv.sql("Select count(*) from table_csv").collect()发布于 2015-11-04 00:06:56
使用不同数据源创建的DataFrames之间应该没有性能差异,它包括JSON或csv。
问题在于,当您在上面的代码段中调用hc_json.sql时,您不仅执行查询,而且每次执行查询时都从磁盘加载数据。这意味着您测量的不是查询时间,而是磁盘访问+解析+查询。对于JSON和csv,第一个*和最后一个应该大致相同,但是解析将因源而异。
如果您只想测量实际的查询时间,您应该缓存数据并执行一个操作,以确保数据已经实际加载。例如
df_csv.registerTempTable("table_csv")
sqlContext.cacheTable("table_csv")
hc_csv.sql("SELECT count(*) FROM table_csv").collect()现在应该加载数据,您可以期待类似的查询时间。
编辑这里实际上还有一个不同之处。从JSON源创建的DataFrame将获得正确的数据类型,而一个数据类型来自csv,而无需提供模式或设置inferSchema选项就可以将所有数据作为字符串读取。
*正如kostya所指出的,JSON文件通常较小。另一方面,与csv不同,JSON很好地处理稀疏日期。
发布于 2015-11-04 00:34:30
许多事情都会影响查询性能,包括:
对于大多数查询,使用CSV很可能更快,因为文件大小小于JSON,需要从磁盘读取的数据也较少。使用拼板文件格式可能会更快,因为更小的文件大小和更快的解码时间。
像(select count(*) from table_csv)这样的查询可以以某些格式运行得更快(例如,parquet),因为如果没有请求列,Spark就足够聪明地跳过读取数据。
@ query 323建议首先在内存中加载数据,这很可能会提高查询执行速度,但如果集群中没有足够的RAM来容纳整个数据集,它将无法工作。
https://stackoverflow.com/questions/33509619
复制相似问题