Hive连接产生笛卡尔集

在使用hive过程中遇到这样的一个异常:

FAILED: ParseException line 1:18 Failed to recognize predicate 'a'. Failed rule: 'kwInner' in join type specifier

执行的hql语句如下:

[root@javachen.com ~]# hive -e 'select a.* from t a, t b where a.id=b.id'

从异常信息中很难看出出错原因,hive.log中也没有打印出详细的异常对战信息。改用jdbc连接hive-server2,可以看到hive-server2中提示如下异常信息:

13/10/17 09:57:48 ERROR ql.Driver: FAILED: ParseException line 1:18 Failed to recognize predicate 'a'. Failed rule: 'kwInner' in join type specifier

org.apache.hadoop.hive.ql.parse.ParseException: line 1:18 Failed to recognize predicate 'a'. Failed rule: 'kwInner' in join type specifier

	at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:446)
	at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:441)
	at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:349)
	at org.apache.hadoop.hive.ql.Driver.compileAndRespond(Driver.java:355)
	at org.apache.hive.service.cli.operation.SQLOperation.prepare(SQLOperation.java:95)
	at org.apache.hive.service.cli.operation.SQLOperation.prepare(SQLOperation.java:76)
	at org.apache.hive.service.cli.operation.SQLOperation.run(SQLOperation.java:114)
	at org.apache.hive.service.cli.session.HiveSessionImpl.executeStatement(HiveSessionImpl.java:194)
	at org.apache.hive.service.cli.CLIService.executeStatement(CLIService.java:155)
	at org.apache.hive.service.cli.thrift.ThriftCLIService.ExecuteStatement(ThriftCLIService.java:191)
	at org.apache.hive.service.cli.thrift.TCLIService$Processor$ExecuteStatement.getResult(TCLIService.java:1193)
	at org.apache.hive.service.cli.thrift.TCLIService$Processor$ExecuteStatement.getResult(TCLIService.java:1)
	at org.apache.thrift.ProcessFunction.process(ProcessFunction.java:39)
	at org.apache.thrift.TBaseProcessor.process(TBaseProcessor.java:39)
	at org.apache.hive.service.cli.thrift.TSetIpAddressProcessor.process(TSetIpAddressProcessor.java:38)
	at org.apache.thrift.server.TThreadPoolServer$WorkerProcess.run(TThreadPoolServer.java:206)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)

从异常信息可以看到是在编译hql语句进行语法解析时出现了错误,到底为什么会出现Failed rule: 'kwInner' in join type specifier这样的异常信息呢?

在eclipse中查找关键字并没有找到相应代码,在Hive.g 中查找关键字“kwInner”,可以看到如下内容:

joinToken
@init { msgs.push("join type specifier"); }
@after { msgs.pop(); }
    :
      KW_JOIN                     -> TOK_JOIN
    | kwInner  KW_JOIN            -> TOK_JOIN
    | KW_CROSS KW_JOIN            -> TOK_CROSSJOIN
    | KW_LEFT  KW_OUTER KW_JOIN   -> TOK_LEFTOUTERJOIN
    | KW_RIGHT KW_OUTER KW_JOIN   -> TOK_RIGHTOUTERJOIN
    | KW_FULL  KW_OUTER KW_JOIN   -> TOK_FULLOUTERJOIN
    | KW_LEFT  KW_SEMI  KW_JOIN   -> TOK_LEFTSEMIJOIN
    ;

从上面可以看出hive支持的连接包括:

  • join
  • inner join
  • cross join (as of Hive 0.10)
  • left outer join
  • right outer join
  • full outer join
  • left semi join

kwInner为什么是小写呢,其含义是什么呢?搜索关键字,找到如下代码:

kwInner
:
{input.LT(1).getText().equalsIgnoreCase("inner")}? Identifier;

上面的大概意思是找到输入左边的内容并判断其值在忽略大小写情况下是否等于inner,大概意思是hql语句中缺少inner关键字吧?修改下hql语句如下,然后执行:

[root@javachen.com ~]#  hive -e 'select a.* from t a inner join t b where a.id=b.id'

修改后的hql语句能够正常运行,并且变成了内连接。在JION接连查询中没有ON连接key而通过WHERE条件语句会产生笛卡尔集。

Hive本身是不支持笛卡尔集的,不能用select T1.*, T2.* from table1, table2这种语法。但有时候确实需要用到笛卡尔集的时候,可以用下面的语法来实现同样的效果:

select T1.*, T2.* from table1 T1 join table2 T2 where 1=1;

注意在Hive的Strict模式下不能用这种语法,因为这样会产生笛卡尔集,而这种模式禁止产生笛卡尔集。需要先用set hive.mapred.mode=nonstrict;设为非strict模式就可以用了,或者将where改为on连接。

select T1.*, T2.* from table1 T1 join table2 T2 on  T1.id=T2.id;

关于Strict Mode

Hive中的严格模式可以防止用户发出(可以有问题)的查询无意中造成不良的影响。 将hive.mapred.mode设置成strict可以禁止三种类型的查询:

1)、在一个分区表上,如果没有在WHERE条件中指明具体的分区,那么这是不允许的,换句话说,不允许在分区表上全表扫描。这种限制的原因是分区表通常会持非常大的数据集并且可能数据增长迅速,对这样的一个大表做全表扫描会消耗大量资源,必须要再WHERE过滤条件中具体指明分区才可以执行成功的查询。

2)、第二种是禁止执行有ORDER BY的排序要求但没有LIMIT语句的HiveQL查询。因为ORDER BY全局查询会导致有一个单一的reducer对所有的查询结果排序,如果对大数据集做排序,这将导致不可预期的执行时间,必须要加上limit条件才可以执行成功的查询。

3)、第三种是禁止产生笛卡尔集。在JION接连查询中没有ON连接key而通过WHERE条件语句会产生笛卡尔集,需要改为JOIN…ON语句。

时间: 2024-12-02 07:44:14

Hive连接产生笛卡尔集的相关文章

笛卡尔集基本原理,等值连接,不等值连接,外连接,自连接

 1笛卡尔集基本原理 两个表如果笛卡尔集运算 (1)行数是两个表行数相乘的结果 (2)列是两个表合集 案例: 错误查询方式: select count(e.EMPNO) from emp e,dept d; 正确查询方式: select count(e.EMPNO) from emp e,dept d where e.deptno = d.deptno; 2.等值连接 Eg:查询员工信息,员工号,姓名,月薪,部门名称 select e.empno,e.ename,e.sal,d.dname

笛卡尔积和NEST LOOP产生的影响

原创 转载请注明出处 SQL 性能分析,笛卡尔积和NEST LOOP SQL> SQL> select * from table(dbms_xplan.display_cursor(null,null,'iostats last')); PLAN_TABLE_OUTPUT-----------------------------------------------------------------------------------------------------------------

基于JS实现的笛卡尔乘积之商品发布_javascript技巧

没给大家介绍正文之前先给大家补充点知识: js笛卡尔积算法 根据给的对象或者数组生成笛卡尔积 //笛卡儿积组合 function descartes(list) { //parent上一级索引;count指针计数 var point = {}; var result = []; var pIndex = null; var tempCount = 0; var temp = []; //根据参数列生成指针对象 for(var index in list) { if(typeof list[ind

c语言-不知道是不是笛卡尔心形函数C语言的编程,,

问题描述 不知道是不是笛卡尔心形函数C语言的编程,, private void Form4_Load(object sender, EventArgs e) { this.BackColor = Color.Black; this.Size = new Size(400, 400); Panel panel = new Panel(); panel.Size = new Size(350, 350); panel.Paint += new PaintEventHandler(panel_Pain

jdbc-JDBC连接hive连接超时

问题描述 JDBC连接hive连接超时 hiveserver2启动了,然后日志也正常,但是用kettle连接或者自己的java代码用jdbc连接都是报错,报错日志如下: java.sql.SQLException: Could not open connection to jdbc:hive2://192.168.162.129:10000/hivedb: java.net.ConnectException: Connection timed out: connect at org.apache

window下myeclipse的插件连接linux的hadoop集群

问题描述 window下myeclipse的插件连接linux的hadoop集群 解决方案 MyEclipse 配置 Hadoop 插件hadoop-1.2.1 win7 myeclipse 插件编译windows/ Linux下 myeclipse和eclipse下安装配置hadoop插件 解决方案二: http://www.silverlightchina.net/html/windows8/study/2013/0203/21803.html

浪漫的笛卡尔:数学家怎样表白

表白?是需要创新的!今天我就教你如何用数学表白. ◆ ◆ ◆ 小故事 笛卡尔,17世纪时出生于法国,他对于后人的贡献相当大,他是第一个创造发明坐标的人,可惜一生穷困潦倒.一直到52岁,仍然默默无名.当时法国正流行黑死病,笛卡尔不得不逃离法国,于是他流浪到瑞典当乞丐. 某天,他在市场乞讨时,有一群少女经过,其中一名少女发现他的口音不像是瑞典人,她对笛卡尔非常好奇,于是上前问他-- 你从哪来的啊? 法国 你是做什么的啊? 我是数学家.这名少女叫克丽丝汀,18岁,是一个公主,她和其它女孩子不一样,并不

net C# 实现任意List的笛卡尔乘积算法

 代码如下 复制代码 using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; namespace 算法 {     public static class 算法     {         /// <summary>         /// 笛卡尔乘积         /// </summary>         public static List&l

笛卡尔乘积介绍_其它相关

笛卡尔(Descartes)乘积又叫直积.假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1), (b,2)}.可以扩展到多个集合的情况.类似的例子有,如果A表示某学校学生的集合,B表示该学校所有课程的集合,则A与B的笛卡尔积表示所有可能的选课情况. 在数学中,两个集合 X 和 Y 的笛卡儿积(Cartesian product),又称直积,表示为 X × Y,是其第一个对象是 X 的成员而第二个对象是 Y 的一个成员