最近有乙個需求,統計每天的新老使用者,日活,周活,月活。
我們每天的增量資料會加入到hive歷史資料表中,包含使用者訪問**的一些資訊,欄位有很多,包括使用者唯一標識guid。
當然了日活,周活,月活就是乙個count(distinct(guid))語句,非常常用的sql。
但是這裡的問題是:
a:每天的新老使用者應該怎麼統計呢?是的,歷史資料裡面是使用者**訪問行為,同乙個使用者在同一天,不同的天都有可能出現,guid在歷史表中會有多次。如果直接join,效能很差,實際上是做了很多不必要的工作。b:這還不簡單,判斷使用者guid是否存在與歷史庫guid中嘛?
a:歷史資料幾十個t,大概一百億行,你要每天將當日資料(2~3億行)與歷史資料幾億行進行join判斷?
b:額,這個,這個,好像不行哦!
解決方案:
維護一張使用者表,裡面有4列:guid, starttime, endtime, num,分別是使用者的guid,第一次訪問時間,最後一次訪問時間,訪問天數;維護了這麼一張使用者表後,接下來就可以寫hql統計業務了,計算當天新老使用者時,只需要與這個歷史庫進行join就行了(目前為止4千萬),當日guid去重後是1千多萬,這樣就是4千萬~1千萬的join了,與開始4千萬~100億的join,效能會有巨大提公升。從某個狀態開始,歷史表中guid是唯一的;
當天資料去重後,與歷史庫join,如果guid在歷史庫出現過,則將endtime更新為當天時間,num加一;
否則,這是乙個新使用者,插入歷史庫,starttime, endtime都為當天時間,num初始值為1。
hive歷史表的設計與hive相關配置
可以看到這裡hive歷史表history_helper需要頻繁修改,hive表支援資料修改需要在$/conf/hive-site.xml中新增事務支援:
為了提高查詢速度,hive歷史表與增量表這裡都分桶,hive-xite.xml配置:
hive.support.concurrencyname>
truevalue>
property>
hive.exec.dynamic.partition.modename>
nonstrictvalue>
property>
hive.txn.managername>
org.apache.hadoop.hive.ql.lockmgr.dbtxnmanagervalue>
property>
hive.compactor.initiator.onname>
truevalue>
property>
hive.compactor.worker.threadsname>
1value>
hive.enforce.bucketingname>
truevalue>
property>
為了提高reduce並行度,也設定一下:
set mapred.reduce
.tasks = 50
;
這個最好在hive命令列配置,表明只在當前程式使用該配置,就不要配置配置檔案了。
歷史庫建表語句:
create
external
table
ifnot
exists hm2.history_helper
( guid string,
starttime string,
endtime string,
num int
)clustered by(guid) into
50 buckets
stored as orc tblproperties ("transactional"="true");
SQL統計每天的登入次數
有乙個登入的log表,所有使用者每登入一次就會留下一條記錄,登入時間的字段是login time,型別為時間戳。現在想要統計每一天的登入次數。1selectcount fromlogin loggroupbyfrom unixtime login time,y m d 如果換一種資料結構,每天,每個...
pgsql查詢統計每天的資料
因為最近一直在使用pg資料庫,然後遇到乙個問題是需要統計每天的資料。表裡有乙個欄位是記錄的建立時間,但是型別卻是timestamp型別,不能直接用group by之類的語句來解決問題。經過一番努力,終於找到解決方案,語句如下 select count 1 substring to char t.cr...
ebay的新老婆skype
編者按 前不久 ebay 宣布以13 億美元現金加 13億 收購網際網路 公司 skype 如果skype 能在2008 年或者2009 年達到財務目標,他們還會再多付 15億美元。skype到底是什麼呢?為什麼身價如此之高呢?全球網路 公司skype由38 歲的瑞典人 niklas zennstr...