簽到提醒推送之MySQL分頁優化

簽到提醒推送之MySQL分頁優化

需求背景

簽到提醒功能,每天18點推送服務通知提醒用戶簽到。推送對象爲昨日簽到,截止推送前未簽到的用戶。

開發過程

數據庫表結構:

CREATE TABLE `cultivate_game_signin` (
  `id` bigint(20) NOT NULL COMMENT '主鍵',
  `uid` bigint(20) DEFAULT NULL COMMENT '用戶id',
  `signin_time` bigint(20) DEFAULT NULL COMMENT '簽到時間',
  `continue_times` int(11) DEFAULT NULL COMMENT '連續簽到次數',
  `singnin_count` int(11) DEFAULT NULL COMMENT '簽到次數',
  `activity_id` bigint(20) DEFAULT NULL COMMENT '活動id',
  `remind_status` tinyint(4) DEFAULT '0' COMMENT '0打開簽到提醒,1關閉簽到提醒',
  PRIMARY KEY (`id`),
  KEY `idx_uid` (`uid`),
  KEY `idx_time` (`signin_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='活動簽到表' 

第一版開發:

select * from cultivate_game_signin where signin_time betweent '2018-1-13 00:00:00' and '2018-1-14 00:00:00' limit 0 , 100;

在定時任務中執行,直至遍歷完所有數據。 第一版上線後基本實現了需求。但是在12月,一次觀察job發現任務竟然執行了9個小時,執行到的翌日凌晨。在pushcode 防打擾策略中其實21點後的推送已經無效了,用戶也不能查收。沒有意義且浪費了資源。

第二版優化:

根據問題排查,由於用戶量激增,目標推送用戶達到了60W。爲了增加用戶留存,保住新增用戶,所以推送優化箭在弦上。

優化過程

優化主要採取了兩點:

  • 線程池優化 設置合理的線程數,在保證服務穩定的情況下推送完畢。這裏不多贅述。
  • 推送接口優化 單單使用MySQL分頁不必多說,偏移量持續增大勢必造成接口性能下降,無法滿足需求。

Limit分頁優化:

推薦分頁: 分頁方式一: Select * from table WHERE id>=23423 limit 11; #10+1 (每頁10條) Select * from table WHERE id>=23434 limit 11; 分頁方式二: Select * from table WHERE id >= ( select id from table limit 10000,1 ) limit 10; 分頁方式三: Select * from table INNER JOIN (SELECT id from table limit 10000,10) USING(id) 分頁方式四: 程序取ID: Select id from table limit 10000,10; Select * from table WHERE ID in(123,456…);

不難看出,優化主要是在解決偏移量過大。

explain select * from cultivate_game_signin where signin_time between 0 and 1540443740869  limit 99,1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE cultivate_game_signin range idx_time idx_time 9 NULL 129940 Using where

掃描數量會越來越大造成性能衰減。所以,在推送優化中使用了id,前提是id有序。

改進後的SQL:

select * from cultivate_game_signin where id > id signin_time betweent begin_time and end_time limit 100;

將id作爲參數,作爲下個執行語句的查詢條件。避免了大偏移量的產生。效果也是立竿見影,30分鐘內可以推送完所有目標用戶。

分頁的指導思想,查詢命中索引並且避免大的偏移量。

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