請教:現在有每天的日表資料(一天產生一張), 每張表資料大概在500w左右。需要從每天的日表資料中統計:根據appid統計ip數,同時ip需要去重。 大概的sql是:
select appid, count(distinct(ip)) from log0812_tb where iptype = 4 group by appid;
然後將統計的appid 和 ip數,放入到另一張統計表中。 1、直接執行sql的話,肯定逾時了(系統僅配置了400ms讀取時間)。2、如果將資料都取出到記憶體中再做操作,記憶體又不足了,給的記憶體只有50M。。。(不為難程式員的需求不是好公司) 請問,還有最佳化的解決方案嗎?謝謝
回複內容:
請教:現在有每天的日表資料(一天產生一張), 每張表資料大概在500w左右。需要從每天的日表資料中統計:根據appid統計ip數,同時ip需要去重。 大概的sql是:
select appid, count(distinct(ip)) from log0812_tb where iptype = 4 group by appid;
然後將統計的appid 和 ip數,放入到另一張統計表中。 1、直接執行sql的話,肯定逾時了(系統僅配置了400ms讀取時間)。2、如果將資料都取出到記憶體中再做操作,記憶體又不足了,給的記憶體只有50M。。。(不為難程式員的需求不是好公司) 請問,還有最佳化的解決方案嗎?謝謝
先說下表上可能的最佳化:
做一個複合式索引(appid, ip)
ip存整數,不要存字串
如果依然逾時,那麼嘗試把資料讀到記憶體,但你的記憶體只有50M,那麼可以嘗試用HyperLogLog,消耗的記憶體是極小的,但統計出來的資料會略有偏差,2%左右
最後,這種日誌資料最好不要放sql,可以選擇一些nosql比如hbase, mongodb都能很好的完成你這個需求
@manong
謝謝,你說的這兩種最佳化方案都不錯。
我建了 typeid、appid、ip的聯合索引, 這樣這條語句時走索引查詢,沒回表,時間控制在了1.5s以下,有效果。
至於HyperLogLog演算法這種,我只是大概查了下,沒有去實踐用,不過也謝謝推薦哈。
我用的另外的方法處理:計劃任務去分批處理這500w+的資料, 兩次取的資料去重後,做array_diff比較出第二次不同的資料,再sum下得出總的count數。 這樣時間也可以控制在1s以下。 這裡有個技巧是將第一次比較的array轉換為string後存入array中, 第二次比較時再string轉array,會省很多記憶體,因為試了下,嵌套數組的話,要比長字串value的數組耗記憶體。