Spark SQL是Spark用来处理结构化数据的一个模块,它提供了2个编程抽象:DataFrame和
DataSet,并且作为分布式SQL查询引擎的作用。
Spark SQL与RDD的关系,类似hive和MR的关系,它是将Spark SQL转换成RDD,然后提交到集群执行,执行效率非常快。
Spark SQL的特点
1)易整合
2)统一的数据访问方式
3)兼容Hive
4)标准的数据连接
DataFrame
在Spark中,DataFrame是一种以RDD为基础的分布式数据集,类似于传统数据库中的二维表格。DataFrame与RDD的主要区别在于,前者带有schema元信息,即DataFrame所表示的二维表数据集的每一列都带有名称和类型。这使得Spark SQL得以洞察更多的结构信息,从而对藏于DataFrame背后的数据源以及作用于DataFrame之上的变换进行了针对性的优化,最终达到大幅提升运行时效率的目标。反观RDD,由于无从得知所存数据元素的具体内部结构,Spark Core只能在stage层面进行简单、通用的流水线优化。
DataFrame也是懒执行的,但性能上比RDD要高。主要原因:
优化的执行计划(例如:谓词下推),即查询计划通过Spark catalyst optimiser进行优化。
DataSet
DataSet是分布式数据集合。DataSet是Spark 1.6中添加的一个新抽象,是DataFrame的一个扩展。它提供了RDD的优势(强类型,使用强大的lambda函数的能力)以及Spark SQL优化执行引擎的优点。DataSet也可以使用功能性的转换(操作map,flatMap,filter等等)。
1)是DataFrame API的一个扩展,是SparkSQL最新的数据抽象;
2)用户友好的API风格,既具有类型安全检查也具有DataFrame的查询优化特性;
3)用样例类来对DataSet中定义数据的结构信息,样例类中每个属性的名称直接映射到DataSet中的字段名称;
4)DataSet是强类型的。比如可以有DataSet[Car],DataSet[Person]。
注意:
DataSet在编译阶段就对数据进行校验(体现在可以直接通过 .列名的方式来索引列),而DataFrame在执行阶段才对数据进行校验(索引列数据,需要知道该列元素的类型,用getXXX()来进行,如果类型不匹配会报错)
SQL风格语法
1)创建一个DataFrame
scala> val df = spark.read.json("/opt/module/spark/examples/src/main/resources/people.json")
df: org.apache.spark.sql.DataFrame = [age: bigint, name: string]
2)对DataFrame创建一个临时表
scala> df.createOrReplaceTempView("people")
3)通过SQL语句实现查询全表
scala> val sqlDF = spark.sql("SELECT * FROM people")
sqlDF: org.apache.spark.sql.DataFrame = [age: bigint, name: string]
4)结果展示
scala> sqlDF.show
+----+-------+
| age| name|
+----+-------+
|null|Michael|
| 30| Andy|
| 19| Justin|
+----+-------+
注意:普通临时表是Session范围内的,如果想应用范围内有效,可以使用全局临时表。使用全局临时表时需要全路径访问,如:global_temp.people
5)对于DataFrame创建一个全局表
scala> df.createGlobalTempView("people")
6)通过SQL语句实现查询全表
scala> spark.sql("SELECT * FROM global_temp.people").show()
+----+-------+
| age| name|
+----+-------+
|null|Michael|
| 30| Andy|
| 19| Justin|
scala> spark.newSession().sql("SELECT * FROM global_temp.people").show()
+----+-------+
| age| name|
+----+-------+
|null|Michael|
| 30| Andy|
| 19| Justin|
+----+-------+