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年的每天10:15運行
"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 * ?" 每月15日10: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 快照表
按天分區,每一天的數據截止到那一天的全量數據,包含歷史數據