hive sql基本語法及注意事項

1、 基本語法

1.1 建表語句

create table IF NOT EXISTS tmp.table_name
(
uid string comment 'uid'
,salary double comment '薪資'

)
partitioned by (pt string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ;

1.2 增加comment

alter table tmp.table_name change column 
age age double comment '年齡'

1.3 更改表名

alter table tmp.table_name rename to tmp.table_name1

1.4 刪除分區

alter table tmp.table_name drop partition (pt='****')

1.5 查看 create table 的具體信息

show create table  tmp.table_name1

1.6 建表降低表的存儲空間

create table IF NOT EXISTS tmp.table_name1
(
uid string comment 'uid'
,salary double comment '薪資'
)
partitioned by (pt string)
row format delimited fields terminated by '\001' lines terminated by '\n'
stored as orc
tblproperties('orc.compress'='ZLIB');

-- 覆蓋增加數據
insert overwrite table tmp.table_name1 partition (pt='${dt}') 
select * from tmp.table_name2

1.7 刪除分區表

-- 刪除分區表
 alter table tmp.table_name1 drop partition (pt='*****');

1.8 調度平臺引入包

-- 調度引入包
set hive.execution.engine=tez;
-- 合併小文件
set hive.map.aggr=true
set hive.merge.mapfiles = true;
set hive.merge.mapredfiles = true;
set hive.exec.max.dynamic.partitions=3000;
set hive.exec.max.dynamic.partitions.pernode=500;
SET hive.tez.container.size=6656;
SET hive.tez.java.opts=-Xmx5120m;
set hive.merge.tezfiles=true;
set hive.merge.smallfiles.avgsize=1280000000;
set hive.merge.size.per.task=1280000000;
set hive.execution.engine=tez;
set tez.am.resource.memory.mb=8192;
-- 涉及數據傾斜的話,主要是reduce中數據傾斜的問題,
-- 可能通過設置hive中reduce的並行數
-- reduce的內存大小單位爲m
-- reduce中 shuffle的刷磁盤的比例
SET mapred.reduce.tasks=50;
SET mapreduce.reduce.memory.mb=6000;
SET mapreduce.reduce.shuffle.memory.limit.percent=0.06;

1.9 hive sql shell 腳本


h_pt=`date -d "+1 hour" +%Y%m%d%H`
re_time_index=`date -d "+1 hour" +%H`
b_2h_time=`date -d "-2 hour" +%H`

`date -d "-2 day" +%Y%m%d`
獲取今天時期:`date +%Y%m%d` 或 `date +%F` 或 $(date +%y%m%d)
獲取昨天時期:`date -d yesterday +%Y%m%d`
獲取前天日期:`date -d -2day +%Y%m%d`
依次類推比如獲取10天前的日期:`date -d -10day +%Y%m%d`
或n天前的 `date -d "n days ago" +%y%m%d`
明天:`date -d tomorrow +%y%m%d`

-- 本月第一天
nowdate=`date +%Y%m01` 
-- 本月最後一天
enddate=`date -d"$(nowdate -d"1 month" +"%Y%m01") -1 day" +"%Y%m%d"`
-- 上個月第一天
startdate=`date -d"$nowdate last month" +%Y%m%d` 
-- 上個月最後一天
enddate=`date -d"$nowdate last day" +%Y%m%d`
-- 短時訂單
(unix_timestamp(stop_time) - unix_timestamp(start_time)) >120
-- 當前時間的前一個小時
select from_unixtime(unix_timestamp(concat(substr('2019073112',1,4),'-',substr('2019073112',5,2),'-',substr('2019073112',7,2),' ',substr('2019073112',9,2),':00:00'))-3600,'yyyyMMddHH')

-- week
IF(pmod(datediff(concat(substr(dt,1,4),'-',substr(dt,5,2),'-',substr(dt,7,2)), '1920-01-01') - 3, 7)='0', 7, pmod(datediff(concat(substr(dt,1,4),'-',substr(dt,5,2),'-',substr(dt,7,2)), '1920-01-01') - 3, 7)) as week


2.0 cron 表達式


-- cron表達式 每週一到週五調度
0 15 10 ? * MON-FRI
"0 0 12 * * ? " 每天12點運行
"0 15 10 ? * *" 每天10:15運行
"0 15 10 * * ?" 每天10:15運行
"0 15 10 * * ? *" 每天10:15運行
"0 15 10 * * ? 2008"2008年的每天1015運行
"0 * 14 * * ?" 每天14點到15點之間每分鐘運行一次,開始於14:00,結束於14:59"0 0/5 14 * * ?" 每天14點到15點每5分鐘運行一次,開始於14:00,結束於14:55"0 0/5 14,18 * * ?" 每天14點到15點每5分鐘運行一次,此外每天18點到19點每5鍾也運行一次。
"0 0-5 14 * * ?" 每天14:00點到14:05,每分鐘運行一次。
"0 10,44 14 ? 3 WED" 3月每週三的14:10分到14:44,每分鐘運行一次。
"0 15 10 ? * MON-FRI" 每週一,二,三,四,五的10:15分運行。
"0 15 10 1 * ?"
"0 15 10 15 * ?" 每月1510:15分運行。
"0 15 10 L * ?" 每月最後一天10:15分運行。
"0 15 10 ? * 6L" 每月最後一個星期五10:15分運行。
"0 15 10 ? * 6L 2007-2009"2007,2008,2009年每個月的最後一個星期五的10:15分運行。
"0 15 10 ? * 6#3" 每月第三個星期五的10:15分運行。

2.1日期加減

-- date_add 增加
select replace(date_add(current_date,1),'-','')
-- date_sub 減少
select replace(date_sub(current_date,1),'-','')
-- 兩個日期相減
select datediff('2019-12-01 23:23:23','2019-02-01 23:23:23')

2.2 row_number()

--row_number()
row_number() OVER (partition by pt,uid order by time_index desc)as row_index

2.3上個月


-- 上個月最後一天
select SUBSTR(DATE_SUB(FROM_UNIXTIME(UNIX_TIMESTAMP()),DAYOFMONTH(FROM_UNIXTIME(UNIX_TIMESTAMP()))),1,10)

-- 上個月第一天
select concat(SUBSTR(DATE_SUB(FROM_UNIXTIME(UNIX_TIMESTAMP()),DAYOFMONTH(FROM_UNIXTIME(UNIX_TIMESTAMP()))),1,7),'-01')

2、注意事項

2.1 join

sql left join和 not in 比較

  • 建議在寫sql語句的時候,儘量避免用not in 而 優先選擇left join,這樣效率會提高很多

2.2 count

  • 儘量用count(1) 而不是count(*)
  • distinct col 返回值中含有null
  • count(col) 返回值不包含null
  • count(distinct col) 返回值不包含(數據量大盡量儘量不要使用count distinct col 換成group by col 然後計算count(1)替代)

2.3 數據傾斜

2.3.1 通過增加reduce數緩解

– 涉及數據傾斜的話,主要是reduce中數據傾斜的問題,
– 可能通過設置hive中reduce的並行數
– reduce的內存大小單位爲m
– reduce中 shuffle的刷磁盤的比例

SET mapred.reduce.tasks=50;
SET mapreduce.reduce.memory.mb=6000;
SET mapreduce.reduce.shuffle.memory.limit.percent=0.06;

2.3.2 map join

在map端完成聚合操作

set hive.map.aggr=true;
-- set hive.exec.parallel 爲true 可控制一個sql中多個可並行執行的job的運行方式
--parallel.thread.number 控制對於同一個sql來說同時可以運行的job的最大值,該參數默認爲8.此時最大可以同時運行8個job.
set hive.exec.parallel.thread.number=16-- 決定  group by 操作是否支持傾斜數據(只能對單個字段聚合)生成兩個mr job
set hive.groupby.skewindata=true 

2.4 合併小文件

-- 加快運行速度
set hive.execution.engine=tez;

-- 合併小文件
set hive.merge.mapfiles = true;
set hive.merge.mapredfiles = true;
set hive.exec.max.dynamic.partitions=3000;
set hive.exec.max.dynamic.partitions.pernode=500;
SET hive.tez.container.size=6656;
SET hive.tez.java.opts=-Xmx5120m;
set hive.merge.tezfiles=true;
set hive.merge.smallfiles.avgsize=1280000000;
set hive.merge.size.per.task=1280000000;
set tez.am.resource.memory.mb=8192;

3 分區表

3.1 全量表

每天全量的數據進行分區,全量表無分區

3.2 增量表

按天分區,每一天的分區存儲那一天產生的數據,如20190512這一天產生的訂單數據,會存儲在分區爲20190512這個分區裏面

3.3 快照表

按天分區,每一天的數據截止到那一天的全量數據,包含歷史數據

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章