天天看点

Hive连接产生笛卡尔集关于Strict Mode

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

执行的hql语句如下:

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

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

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

join

inner join

cross join (as of Hive 0.10)

left outer join

right outer join

full outer join

left semi join

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

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

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

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

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

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

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

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

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