hive和mysql有什么不同
- 1.不支持下列from a,b where用法
SQL中对两表内联可以写成:select * from dual a,dual b where a.key = b.key;
Hive中应为:select * from dual a join dual b on a.key = b.key
- 2.不能智能识别concat(‘;’,key),只会将‘;’当做SQL结束符号
- 3.不支持INSERT INTO 表 Values(), UPDATE, DELETE等操作
- 4.HiveQL中String类型的字段若是空(empty)字符串, 即长度为0, 那么对它进行IS NULL的判断结果是False
- 5.join的时候不支持非等值连接
- 6.on中不支持or
- 7.对于orderby语句,必然要使用limit语句(防止reducer额外执行很长时间)
关于5,join的时候不支持非等值连接怎么处理
处理办法1:把非等值连接的key放在case when语句
处理办法2:把非等值连接放在where之后再用大表left join避免缺失信息
处理3:如果不存在等值连接 只存在等值连接的做法 :on true
SELECT *
FROM table1
RIGHT JOIN table2
ON table2.x LIKE CONCAT('%' , table2.y , '%')
转化hive
SELECT *
FROM table1
RIGHT JOIN table2
ON(TRUE)
WHERE instr(table1.y,table2.x)>0
4.hive中null的存储方式
1)不同数据类型对空值的存储规则
int与string类型数据存储,null默认存储为 \N;外表展示为null,可以用is null识别
string类型的数据如果为"",存储则是"",这个时候外表展示不是null,所以不能用is null识别
另外往int类型的字段插入数据“”时,结果还是\N
因此在不设置任何参数情况下,int数据的null可以用is null识别;但是string类型中既想取null又想取空字符串‘’【一定意义下也是确实值】就不能只用is null了
2)解决办法
2.1 再加一个条件:通过 a='' 或者 length(a)=0
2.2 设置参数 SET SERDEPROPERTIES('serialization.null.format' = '') 这样内部null表示为‘’,外表为null,就可以只使用一个条件is null来识别
参考链接:http://www.voidcn.com/article/p-aahpewna-bpb.html
6.hive大表连接小表:设置mapjoin【提高性能】
hive大表连接大表:设置SMBjoin【提高性能】
详情:https://www.cnblogs.com/raymoc/p/5323824.html
7.几个有关null的函数
- 1.NVL函数
- NVL函数的格式如下:NVL(expr1,expr2)
- 如果oracle第一个参数为空那么显示第二个参数的值,如果第一个参数的值不为空,则显示第一个参数本来的值。
- 2.NVL2函数
- NVL2函数的格式如下:NVL2(expr1,expr2, expr3)
- 如果该函数的第一个参数为空那么显示第三个参数的值,如果第一个参数的值不为空,则显示第二个参数的值。
- 3.NULLIF函数
- NULLIF(exp1,expr2)
- 函数的作用是如果exp1和exp2相等则返回空(NULL),否则返回第一个值
- 4.Coalesce函数
- Coalesce(expr1, expr2, expr3….. exprn)
- 一句话就是显示第一个不为空的参数。如果全部为空则返回空.
8.多表join连接时,如果每个on子句都使用相同的连接键的话,那么只会产生一个mapreduce job
select
*
from
table t1
join
table t2
on
t1.key=t2.key
join
table t3
on
t1.key=t3.key -- 不要用t2.key=t3.key
9.hive假定查询中最后一个表是最大的那个表,在对每行记录进行联结操作是,他会尝试将其他表缓存起来,然后扫描最后那个表进行计算,因此最好表的大小从左到右依次递增
10.大表联结小表用mapjoin可以忽略掉常规的reduce操作
11.create database if not exists table_name
12.overwrite关键字会覆盖
insert overwrite table table_name
parition (country = 'US',state = 'OR')
select * from table_name2 as se
where se.cnty = 'US' and se.st = 'OR';
下面这个没有overwrite关键字的只是追加不会覆盖
insert into table table_name
parition (country = 'US',state = 'OR')
select * from table_name2 as se
where se.cnty = 'US' and se.st = 'OR';
13.浮点数的比较
0.2对于float类型来说是0.2000001对于double来说是0.20000000001
当表中的float值通过hive转换为double时,产生的double值是0.2000001,要比0.20000000001 大,因此
select * from employee as e where tax > 0.2;会发现tax=0.2值也会出现
规避方法
select * from employee as e where tax > cast (0.2 as float)
14.抽样
select * from numbers tablesample(bucket 3 out of 10 on rand()) S;
15.sql调优补充
a。用exists/join代替in
b。能用where过滤的不要having
c。使用索引
d。索引条件涉及到计算时,将计算式子放在右边,索引上面不要加;id>=100/2(OK) id*2>=100(NO)