文章目录
背景
SQL:结构化查询语言,主要用来进行统计分析。
Oracle、MySQL、DB2、SQLserver等关系型数据库都用SQL。但是这些关系型数据库对数据量是有限制的。
但是随着互联网的发展,数据量越来越大,关系型数据库越来越难操作这些大数据量的数据。越来越多的传统行业,比如银行、保险等会把原来传统的数据库逐渐’云化’,转到大数据上面来进行操作。但是传统的那些语句分析、优化等的SQL,不会轻易改变,如果发生改变就意味着很多业务逻辑的修改,所以在传统向大数据平台迁移到过程中尽可能保持原有的SQL不发生改变。但是不可能都不会改变,就算Oracle和MySQL数据库,也有些SQL不一样的语法。传统的数据库SQL在大数据里面的SQL,比如hiveSQL,如果找不到相关的,就是说hiveSQL不支持传统数据库的SQL,那么就需要开发大量的udf函数了,udf函数支持原有RDBMS内置的一些函数。当然udf还有其它比如业务需要的专门的udf函数的。
一个框架如果最终不能落地到SQL,那么这个框架是不太行的。
举个例子,如果你要客户通过某个语言比如Python、scala、Java去开发RDD,或者用Java开发MapReduce,来达到处理某个业务的目的,那么肯定是很困难的,这个对客户要求而言太高了。虽然RDD运行起来很快,但是不可行。那如果,现在让客户用SQL就可以处理这些业务,那么就很简单了,SQL相对来说,SQL简单易用,很多人都可以掌握。
大数据平台数据库比如:SQL on Hadoop(广义)
从传统关系型数据库向大数据平台数据库迁移需要考虑①②③:
- ①SQL
- ②存储:
关系型数据库里的数据是存在本地的文件上的,对数据的大小有限制。
大数据平台上的数据库,数据可以存储在分布式文件系统上,比如HDFS上面。 - ③计算:
关系型数据库,比如MySQL数据库引擎:ISAM、MyISAM、InnoDB、MEMORY、HEAP,用这些进行计算分析处理
大数据平台上的数据库,比如MapReduce或者Spark等计算框架,用这些进行计算分析处理
在传统向大数据平台迁移到过程中尽可能保持原有的SQL不发生改变,而去修改优化存储框架和计算框架。
SQL on Hadoop框架介绍
比如
①Hive SQL:
Hive:它运用的计算框架可以是:MapReduce、Tez、Spark(可以通过配置来切换)
在Hive上运行SQL,它会把SQL转换为底层的MapReduce作业、Tez作业、Spark作业。
metastore元数据信息:很多SQL on Hadoop框架都共用metastore的,比如hive上面创建的表,用spark SQL等框架也可以访问,因为它们共用一个metastore。
数据地图,hive元数据整个体系的UML图,通过这个数据地图可以知道整个集群上所有的,一个数据存储量,比如哪个业务占用多少存储空间。这个对公司的成本控制有很大帮助的,你可以知道最近数据存储量增加了多少。
②Impala:
它为了解决hive中交互式查询比较慢的问题。它也是用SQL,它的底层是有自己的一些守护进程的。它和hive共享metastore。hive里面有的,在Impala里面也可以访问。Impala推荐使用的数据存储格式为parquet。但是其它比如hive的存储不是parquet格式的,现在用Impala来查询,肯定需要先转换一下的。可以用Spark SQL来进行转换。
相对来说,Impala是很消耗资源的,比如memory。所以一般机器最好不要用。
③Presto:京东用的就是这个
Distributed SQL Query Engine for Big Data
Presto is an open source distributed SQL query engine for running interactive analytic queries against data sources of all sizes ranging from gigabytes to petabytes.
Presto was designed and written from the ground up for interactive analytics and approaches the speed of commercial data warehouses while scaling to the size of organizations like Facebook.
④Drill :这个还是不错的
Schema-free SQL Query Engine for Hadoop, NoSQL and Cloud Storage
Drill supports a variety of NoSQL databases and file systems, including HBase, MongoDB, MapR-DB, HDFS, MapR-FS, Amazon S3, Azure Blob Storage, Google Cloud Storage, Swift, NAS and local files. A single query can join data from multiple datastores. For example, you can join a user profile collection in MongoDB with a directory of event logs in Hadoop.
Drill’s datastore-aware optimizer automatically restructures a query plan to leverage the datastore’s internal processing capabilities. In addition, Drill supports data locality, so it’s a good idea to co-locate Drill and the datastore on the same nodes.
⑤Phoenix
OLTP and operational analytics for Apache Hadoop
http://phoenix.apache.org/
https://github.com/apache/phoenix
Spark SQL概述
官网:http://spark.apache.org/sql/
Spark SQL是Spark 1.0出来的,1.3毕业的。
Spark SQL is Apache Spark’s module for working with structured data.
Spark SQL是Apache Spark中的一个模块,用来处理结构化数据的。
需要注意的是:Spark SQL只是用来处理结构化数据的一种渠道而已。并不是简简单单的写SQL。Spark SQL是通过sql、DataFrame、DataSet来处理结构化的数据,其中SQL只是占到Spark SQL其中一点点的部分。
结构化数据:可以理解为类似表一样的,有列、有列名。表是结构化数据,ORC和Parquet格式的数据也是结构化数据。JSON也是。
Spark SQL框架在一开始分的时候分为两个分支:
①Spark分支:Spark SQL
②Hive on Spark
这个意思是:Hive跑在Spark之上,之前学的是跑在MapReduce之上,只需要set hive.execution.engine=spark;
这样设置一下即可。
这个生产上面慎用,里面有很多缺陷。
https://cwiki.apache.org/confluence/display/Hive/Hive+on+Spark:+Getting+Started
特点:
①Integrated 集成
Seamlessly mix SQL queries with Spark programs.
无缝地将SQL查询与Spark程序混合。
Spark SQL lets you query structured data inside Spark programs, using either SQL or a familiar DataFrame API. Usable in Java, Scala, Python and R.
Spark SQL可以让你查询结构化数据内嵌到Spark应用程序里面,比如SQL或者DF API。在 Java, Scala, Python and R的Spark应用程序里都是可以使用的。
②Uniform Data Access 统一的数据访问
Connect to any data source the same way.
用相同的方式访问任何数据源
DataFrames and SQL provide a common way to access a variety of data sources, including Hive, Avro, Parquet, ORC, JSON, and JDBC. You can even join data across these sources.
③Hive Integration Hive集成
Run SQL or HiveQL queries on existing warehouses.
在已经存在的数据仓库上面能够运行SQL或者HiveQL的查询。意思就是原来的数据仓库是用HiveQL来实现的,那么你可以用Spark SQL来对接。因为共用metastore,SerDes,and UDFs。
Spark SQL supports the HiveQL syntax as well as Hive SerDes and UDFs, allowing you to access existing Hive warehouses.
Spark SQL支持HiveQL 语法以及 Hive SerDes和UDF,允许您访问现有的Hive 仓库。
④Standard Connectivity标准连接
Connect through JDBC or ODBC.
A server mode provides industry standard JDBC and ODBC connectivity for business intelligence tools.
就是Spark SQL拥有标准的JDBC and ODBC连接,那么你可以用BI的工具来进行访问,然后查询数据。
用BI 工具,通过JDBC/ODBC查询Spark SQL里的结果数据或者统计数据。不可能去查询大量的数据,那样通过JDBC是不行的。
⑤Performance & Scalability 性能和可扩展
Spark SQL includes a cost-based optimizer, columnar storage and code generation to make queries fast. At the same time, it scales to thousands of nodes and multi hour queries using the Spark engine, which provides full mid-query fault tolerance. Don’t worry about using a different engine for historical data.
⑥Community
Spark SQL, DataFrames and Datasets 向导
官网:http://spark.apache.org/docs/latest/sql-programming-guide.html
官网的每句话,都值得去理解,用例子和上面每句话对的上来,去深层次理解。
Spark SQL是Spark中处理结构化数据的模块。与基础的Spark RDD API不同,Spark SQL所提供的接口为Spark提供了更多关于数据的结构信息和正在执行的计算结构的信息。(这个更多的信息指的是schema,比如列名以及数据类型)。Spark SQL 在其内部利用这些额外的信息去做更多的优化。有几种用于和 Sparrk SQL交互的方法,包括 SQL语句 、Dataset API和DataFrame API。 当你运行一个计算去得到一个计算结果, 会使用同一个执行引擎, 无论你使用哪种API或语言来描述这个计算,Spark SQL使用的执行引擎都是同一个。这种底层的统一,使开发者可以在不同的API之间来回切换,你可以选择一种最自然的方式,来表达你的需求。
SQL
Spark SQL的一种用法是直接执行SQL查询语句,你可使用最基本的SQL语法,也可以选择HiveQL语法。Spark SQL可以从已有的Hive中读取数据。更详细的请参考Hive Tables 这一节。如果用其他编程语言运行SQL,Spark SQL将以Dataset 或者DataFrame返回结果。你同样可以使用命令行或者 JDBC/ODBC 与 SQL 接口进行交互。
Datasets and DataFrames
- Datasets
A Dataset is a distributed collection of data.
Dataset 是一种分布式数据集合,是 Spark1.6 新增的接口。
它提供了RDD(强类型,可以使用强大的 lambda 表达式)的优点,并受益于Spark SQL 的优化执行引擎。Dataset 可以通过 JVM 构建,然后在Dataset上可以使用各种transformation算子进行操作(map,flatMap,filter 等)。Dataset API 在 Java 和 Scala 中可用。 Python 并不支持Dataset API。 但是由于Python的动态特性优势(例如,你可以使用row.columnName
来访问每一行的字段),这些优势都可以去利用。R 语言的情况类似。
- DataFrame
DataFrame是Spark1.3版本出来的。 1.3之前它的名字叫做SchemaRDD。
A DataFrame is a distributed collection of data organized into named columns.
DataFrame是一个Dataset,它是一种分布式数据集合,就是说它是一个集合,集合里面有很多数据,数据又被组织成带有名字的列。你可以把它等价于数据库里面的表,有数据有列名,你暂且可以认为DataFrame就是一个table。那么因为这个特性,你就可以写SQL了,很方便。而且它在底层还做了很多的优化。你要用RDD写,也可以,但是编程很痛苦,写出来的代码性能也不确定。
DataFrame是一个Dataset,它每一条数据都由几个命名字段组成。 它在概念上等价于关系型数据库的一个表或者 R/Python 的一个data frame, 但是它(DataFrame)在底层做了更多的优化。DataFrame 可以通过大量的数据源构建,例如:结构化的数据文件, HIVE 的表,外部数据库,或已有的RDD。Java、Python、Scala、R语言都支持 DataFrame API。 在 Scala 和 Java, DataFrame 由Dataset的 rowS 表示。 在 Scala API 中,DataFrame 可以简单地认为是 Dataset[Row] 的别名,就是说:DataFrame =Dataset[Row] 。 然而,在 Java API 中, 用户需要使用 Dataset<Row> 来表示 DataFrame。
面试题:RDD、DataFrame、Dataset的区别?
三个都是分布式的数据集合,都可以进行分布式执行。
一个RDD,它里面的元素有一个类型,比如你读取一个文件给一个RDD,这个RDD里面元素是String类型,但是具体里面有什么,比如有没有列,它并不知道,它不知道里面的具体信息。
但是DataFrame你暂且可以认为就是一个table,就是一个表,它是有各个列的,每个列都有它的数据。它是知道里面的详细信息的。
这个在官网一开始就给了解释:
Spark SQL is a Spark module for structured data processing.
Unlike the basic Spark RDD API,
the interfaces provided by Spark SQL provide Spark with more information
about the structure of both the data and the computation being performed.
Internally, Spark SQL uses this extra information to perform extra optimizations.
Spark SQL比Spark RDD提供了more information,就是named columns,包括the structure of the data和the structure of the computation being performed。即数据的结构和内部计算的结构。
①数据的结构就是上面的集合里面有很多数据,数据又被组织成带有名字的列,每个列都有它的数据。
②计算的结构,比如说现在是列式存储,它计算的时候按照 列 来进行计算,比较快。
③第三个角度
用Java或scala写的RDD,跑在JVM里面,用的是JVM执行引擎;Python写的RDD,用的是它自己的执行引擎。同样的功能,使用相似的代码,使用Java或scala,或者Python,这两种去开发,结果执行性能肯定不一样,差别非常大,Python是非常的慢。
现在有了DataFrame,不管你用Java或scala或者Python哪种语言开发的代码,中间都要转成逻辑执行计划,后面执行都是一样的,所以它们性能一样的。
入口点SparkSession
Spark 所有功能的入口是 SparkSession 类,是整个Spark的入口点。
以前在Spark SQL里有两个入口:SQLContext(不支持Hive)和HiveContext(支持Hive),HiveContext继承了SQLContext,所以用HiveContext就可以了,而发展到现在全部的Spark都用SparkSession作为入口。
创建最基本的 SaprkSession, 只需要调用 SparkSession.builder():
scala版:
import org.apache.spark.sql.SparkSession
val spark = SparkSession
.builder()
.master("local[2]")
.appName("Spark SQL basic example")
.config("spark.some.config.option", "some-value")
.getOrCreate()
// For implicit conversions like converting RDDs to DataFrames
//用于像 RDD到DataFrame 隐式转换操作
import spark.implicits._
spark.stop()
上面这些设置,最好不要写在代码里,推荐在用spark-submit提交的时候设置。
在 Spark 仓库 “examples/src/main/java/org/apache/spark/examples/sql/JavaSparkSQLExample.java”
中可以找到完整的示例代码。这个示例代码非常好,对于学习非常有帮助。要非常熟悉这里面的示例。
[hadoop@hadoop001 sql]$ pwd
/home/hadoop/app/spark-2.4.2-bin-2.6.0-cdh5.7.0/examples/src/main/scala/org/apache/spark/examples/sql
[hadoop@hadoop001 sql]$ ls
hive SparkSQLExample.scala streaming UserDefinedUntypedAggregation.scala
RDDRelation.scala SQLDataSourceExample.scala UserDefinedTypedAggregation.scala
[hadoop@hadoop001 sql]$ cd ..
[hadoop@hadoop001 examples]$ ls
BroadcastTest.scala HdfsTest.scala LogQuery.scala SkewedGroupByTest.scala SparkPi.scala
DFSReadWriteTest.scala LocalALS.scala ml SparkALS.scala SparkRemoteFileTest.scala
DriverSubmissionTest.scala LocalFileLR.scala mllib SparkHdfsLR.scala SparkTC.scala
ExceptionHandlingTest.scala LocalKMeans.scala MultiBroadcastTest.scala SparkKMeans.scala sql
graphx LocalLR.scala pythonconverters SparkLR.scala streaming
GroupByTest.scala LocalPi.scala SimpleSkewedGroupByTest.scala SparkPageRank.scala
[hadoop@hadoop001 examples]$
Spark2.0 的 SparkSession 提供了对 HIVE 特性的内置支持, 包括使用 HiveQL 编写查询语句的能力,访问 Hive UDFs 和 从 Hive Table 中读取数据的能力。为了使用这些特性,您不需要去安装一个 HIVE。
Spark SQL整合Hive以及性能对比
现在你要用Spark SQL来访问hive里面的表,需要做以下操作:
①把$HIVE_HOME/conf/hive-site.xml
拷贝到$SPARK_HOME /conf/
下
[hadoop@hadoop001 conf]$ pwd
/home/hadoop/app/hive-1.1.0-cdh5.7.0/conf
[hadoop@hadoop001 conf]$ cp hive-site.xml /home/hadoop/app/spark-2.4.2-bin-2.6.0-cdh5.7.0/conf
②因为hive的数据都是存放在hdfs上面的,所以需要把hdfs启动起来。当然yarn也要启动起来。
③需要添加MySQL的jar包,因为要访问元数据,元数据是存放在MySQL里的。
用下面命令启动spark-shell;
spark-shell --master local[2] --jars ~/soft/mysql-connector-java.jar
这样就可以用Spark SQL来访问hive里面的表了。
Spark context Web UI available at http://hadoop001:4040
Spark context available as 'sc' (master = local[2], app id = local-1561878671792).
Spark session available as 'spark'.
可以看到Spark context用sc,Spark session用spark来表示。
scala> spark.sql("show databases").show;
+------------+
|databaseName|
+------------+
| default|
| g6|
+------------+
scala> spark.sql("select * from g6.test").show;
+--------+---+---+
| name|sex|age|
+--------+---+---+
|zhangsan| m| 16|
+--------+---+---+
Spark SQL和HiveQL性能对比:
scala> spark.sql("select * from dept").show;
+------+----------+-------+
|deptno| dname| loc|
+------+----------+-------+
| 10|accounting|newyork|
| 20| research| dallas|
| 30| sales|chicago|
| 40|operations| boston|
+------+----------+-------+
scala> spark.sql("select * from emp").show;
+----+------+---------+----+----------+-------+------+------+
| emp| ename| job| mgr| hiredate| sal| comm|deptno|
+----+------+---------+----+----------+-------+------+------+
|7369| SMITH| CLERK|7902|1980-12-17| 800.0| null| 20|
|7499| ALLEN| SALESMAN|7698|1981-02-20| 1600.0| 300.0| 30|
|7521| WARD| SALESMAN|7698|1981-02-22| 1250.0| 500.0| 30|
|7566| JONES| MANAGER|7839|1981-04-02| 2975.0| null| 20|
|7654|MARTIN| SALESMAN|7698|1981-09-28| 1250.0|1400.0| 30|
|7698| BLAKE| MANAGER|7839|1981-05-01| 2850.0| null| 30|
|7782| CLARK| MANAGER|7839|1981-06-09| 2450.0| null| 10|
|7788| SCOTT| ANALYST|7566|1987-04-19| 3000.0| null| 20|
|7839| KING|PRESIDENT| |1981-11-17| 5000.0| null| 10|
|7844|TURNER| SALESMAN|7698|1981-09-08| 1500.0| 0.0| 30|
|7876| ADAMS| CLERK|7788|1987-05-23| 1100.0| null| 20|
|7900| JAMES| CLERK|7698|1981-12-03| 950.0| null| 30|
|7902| FORD| ANALYST|7566|1981-12-03| 3000.0| null| 20|
|7934|MILLER| CLERK|7782|1982-01-23| 1300.0| null| 10|
|8888| HIVE| PROGRAM|7839|1988-01-23|10300.0| null| null|
+----+------+---------+----+----------+-------+------+------+
现在用Spark SQL和HiveQL分别对两个表做join,看一下时间长短。
Spark SQL执行:
scala> spark.sql("select * from emp join dept on emp.deptno = dept.deptno").show;
HiveQL执行:
select * from emp join dept on emp.deptno = dept.deptno;
结果发现,Spark SQL执行完命令瞬间就出来结果了,而HiveQL跑出结果的时间为10几秒,要慢很多。
另外:
spark编译的时候,要加上下面参数,不然 Spark SQL集成不了Hive。
使用spark-sql替换spark-shell
上面是使用spark-shel来操作的,现在用spark-sql来操作,是一样的。
可以用下面来启动spark-sql
spark-sql --master local[2] --jars ~/soft/mysql-connector-java.jar
但是启动的时候报错,
java.sql.SQLException: Unable to open a test connection to the given database. JDBC url = jdbc:mysql。。。。。。
java.sql.SQLException: No suitable driver found for jdbc:mysql://。。。。。。。
报错,原因:
用spark-shell --help或者spark-sql --help看一下,有两个参数:
//--jars 会把jar包传到driver端和executor 端,但是有时候会传不到driver端
//官方上面也有不对的地方
--jars JARS Comma-separated list of jars to include on the driver
and executor classpaths.
//如果上面传不到driver端,那么就用这个把jar包传到driver端
//jars added with --jars 这个东西有时候不准,有些版本不能自动添加,就像上面那样就没有自动添加
-driver-class-path Extra class path entries to pass to the driver. Note that
jars added with --jars are automatically included in the
classpath.
于是用下面这种方式来启动,可以启动:
//小知识点:spark-sql 底层调用的也是spark-submit
spark-sql --master local[2] --driver-class-path ~/soft/mysql-connector-java.jar
举例:
spark-sql (default)> select * from dept;
......
10 accounting newyork
20 research dallas
30 sales chicago
40 operations boston
Time taken: 1.422 seconds, Fetched 4 row(s)
19/06/30 16:21:21 INFO SparkSQLCLIDriver: Time taken: 1.422 seconds, Fetched 4 row(s)
spark-sql (default)>
你那边在hive创建的表,这边就可以使用Spark SQL来访问了。
因为它们用的都是同一个metastore,你可以随意切换计算框架,可以用hive也可以用Spark SQL,或者其它。
小知识点:
用下面命令启动:
spark-shell --master local[2] --jars ~/soft/mysql-connector-java.jar
启动之后去webUI 页面的Environment里面看一下,Classpath Entries这个属性下面,有很多很多jar包,这是 $SPARK_HOME/jars/下面的jar包, 每次都要上传上去的,基本都是System Classpath,但是拉到最下面,可以看到mysql-connector-java.jar 这个是Added By User,就是被用户添加的。可以把需要的jar包放在 $SPARK_HOME/jars/ 这个目录,但是要根据需要,很多情况下并不需要,放在这个目录,可能会影响别人的操作。
生产上,如果你添加了jar包,发现少了几个,你可以通过这种方式来查看。
cache 一个表到内存中
现在把emp这个表持久化到内存中:
cache table emp;
到web UI页面上的Storage页面就可以看到了:
从上面可以看出,Spark SQL里的cache操作并不是lazy的,它是eager的,Spark core里面的cache是lazy的。
去除表emp的缓存:
uncache table emp;
另外需要注意的是,如果Spark SQL要访问Hive里的数据,并不需要安装Hive,只需要Spark SQL能够访问metastore就行了,只是这里巧了,只要用hive-site.xml就可以访问metastore了,因为这里面有metastore的配置信息。
Spark SQL 之 thriftserver和beeline
和Hive一样,Spark SQL也可以使用thriftserver和beeline。
第一步启动thriftserver:
//小知识点:--jars ~/soft/mysql-connector-java.jar 这个东西可以配置到spark-defaults.conf里面
//这样就不用每次都要添加jars了,包括spark-shell和spark-sql
[hadoop@hadoop001 sbin]$ ./start-thriftserver.sh --jars ~/soft/mysql-connector-java.jar
starting org.apache.spark.sql.hive.thriftserver.HiveThriftServer2, logging to /home/hadoop/app/spark-2.4.2-bin-2.6.0-cdh5.7.0/logs/spark-hadoop-org.apache.spark.sql.hive.thriftserver.HiveThriftServer2-1-hadoop001.out
tail一下上面的…out日志,看一下启动起来了:
INFO AbstractService: Service:ThriftBinaryCLIService is started.
INFO AbstractService: Service:HiveServer2 is started.
INFO HiveThriftServer2: HiveThriftServer2 started
INFO ThriftCLIService: Starting ThriftBinaryCLIService on port 10000 with 5...500 worker threads
第二步启动beeline:
//注意,这里要用当前目录./来执行,不然hive里也有beeline,如果直接beeline启动,有可能启动的是hive里的,因为环境变量里可能把hive的配置到spark前面了
[hadoop@hadoop001 spark-2.4.2-bin-2.6.0-cdh5.7.0]$ ./bin/beeline -u jdbc:hive2://hadoop001:10000 -n hadoop
Connecting to jdbc:hive2://hadoop001:10000
log4j:WARN No appenders could be found for logger (org.apache.hive.jdbc.Utils).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Connected to: Spark SQL (version 2.4.2)
Driver: Hive JDBC (version 1.2.1.spark2)
Transaction isolation: TRANSACTION_REPEATABLE_READ
Beeline version 1.2.1.spark2 by Apache Hive
0: jdbc:hive2://hadoop001:10000> select * from dept;
+---------+-------------+----------+--+
| deptno | dname | loc |
+---------+-------------+----------+--+
| 10 | accounting | newyork |
| 20 | research | dallas |
| 30 | sales | chicago |
| 40 | operations | boston |
+---------+-------------+----------+--+
4 rows selected (2.245 seconds)
0: jdbc:hive2://hadoop001:10000>
0: jdbc:hive2://hadoop001:10000> show tables;
+-----------+---------------+--------------+--+
| database | tableName | isTemporary |
+-----------+---------------+--------------+--+
| default | dept | false |
| default | emp | false |
| default | sparksqltest | false |
+-----------+---------------+--------------+--+
3 rows selected (0.066 seconds)
0: jdbc:hive2://hadoop001:10000>
Spark SQL架构流程
和Hive里面的执行过程是一样的。
https://www.cnblogs.com/ulysses-you/p/9762133.html
用下面这个语句看一下执行计划:
explain extended
select
a.id*(4+5),
b.name
from
sparksqltest a join sparksqltest b
on a.id = b.id and a.id>10;
spark-sql (default)> explain extended
> select
> a.id*(4+5),
> b.name
> from
> sparksqltest a join sparksqltest b
> on a.id = b.id and a.id>10;
INFO HiveMetaStore: 0: get_table : db=default tbl=sparksqltest
INFO audit: ugi=hadoop ip=unknown-ip-addr cmd=get_table : db=default tbl=sparksqltest
INFO HiveMetaStore: 0: get_table : db=default tbl=sparksqltest
INFO audit: ugi=hadoop ip=unknown-ip-addr cmd=get_table : db=default tbl=sparksqltest
INFO CodeGenerator: Code generated in 6.774914 ms
== Parsed Logical Plan ==
'Project [unresolvedalias(('a.id * (4 + 5)), None), 'b.name]
+- 'Join Inner, (('a.id = 'b.id) && ('a.id > 10))
:- 'SubqueryAlias `a`
: +- 'UnresolvedRelation `sparksqltest`
+- 'SubqueryAlias `b`
+- 'UnresolvedRelation `sparksqltest`
== Analyzed Logical Plan ==
(id * (4 + 5)): int, name: string
Project [(id#173 * (4 + 5)) AS (id * (4 + 5))#177, name#176]
+- Join Inner, ((id#173 = id#175) && (id#173 > 10))
:- SubqueryAlias `a`
: +- SubqueryAlias `default`.`sparksqltest`
: +- HiveTableRelation `default`.`sparksqltest`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [id#173, name#174]
+- SubqueryAlias `b`
+- SubqueryAlias `default`.`sparksqltest`
+- HiveTableRelation `default`.`sparksqltest`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [id#175, name#176]
== Optimized Logical Plan ==
Project [(id#173 * 9) AS (id * (4 + 5))#177, name#176]
+- Join Inner, (id#173 = id#175)
:- Project [id#173]
: +- Filter (isnotnull(id#173) && (id#173 > 10))
: +- HiveTableRelation `default`.`sparksqltest`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [id#173, name#174]
+- Filter ((id#175 > 10) && isnotnull(id#175))
+- HiveTableRelation `default`.`sparksqltest`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [id#175, name#176]
== Physical Plan ==
*(5) Project [(id#173 * 9) AS (id * (4 + 5))#177, name#176]
+- *(5) SortMergeJoin [id#173], [id#175], Inner
:- *(2) Sort [id#173 ASC NULLS FIRST], false, 0
: +- Exchange hashpartitioning(id#173, 200)
: +- *(1) Filter (isnotnull(id#173) && (id#173 > 10))
: +- Scan hive default.sparksqltest [id#173], HiveTableRelation `default`.`sparksqltest`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [id#173, name#174]
+- *(4) Sort [id#175 ASC NULLS FIRST], false, 0
+- Exchange hashpartitioning(id#175, 200)
+- *(3) Filter ((id#175 > 10) && isnotnull(id#175))
+- Scan hive default.sparksqltest [id#175, name#176], HiveTableRelation `default`.`sparksqltest`, org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe, [id#175, name#176]
Time taken: 0.148 seconds, Fetched 1 row(s)
INFO SparkSQLCLIDriver: Time taken: 0.148 seconds, Fetched 1 row(s)
spark-sql (default)>