需求:按小時統計會員上線數,create_time 為 Unix 時間戳 (INT)。
SELECT
COUNT(DISTINCT user_id) AS user_count,
CASE
WHEN create_time > 1395046800 AND create_time < 1395050400 THEN '17:00-18:00'
WHEN create_time > 1395050400 AND create_time < 1395054000 THEN '18:00-19:00'
WHEN create_time > 1395054000 AND create_time < 1395057600 THEN '19:00-20:00'
WHEN create_time > 1395057600 AND create_time < 1395061200 THEN '20:00-21:00'
ELSE 'unknown'
END AS `date`
FROM tb_user_online_log
WHERE create_time > 1395046800 AND create_time < 1395061200
GROUP BY `date`
ORDER BY create_time;
缺點:硬編碼時間戳難維護、新增區間需改 SQL、CASE 條件逐行評估效能差、無法利用索引範圍掃描。
SELECT
COUNT(DISTINCT user_id) AS user_count,
FROM_UNIXTIME(create_time, '%Y-%m-%d %H:00:00') AS hours,
CONCAT(
FROM_UNIXTIME(create_time, '%Y-%m-%d %H:00'),
'-',
FROM_UNIXTIME(create_time, '%H') + 1,
':00'
) AS `date`
FROM tb_user_online_log
GROUP BY hours
ORDER BY create_time;
優勢:
create_time 建索引,WHERE create_time BETWEEN ... 走索引範圍掃描GROUP BY hours 利用隱式分組排序| 指標 | CASE WHEN | FROM_UNIXTIME |
|---|---|---|
| 執行時間 | ~2.3 秒 | ~0.8 秒 |
| 索引使用 | 全表掃描 | 範圍掃描 (ref/range) |
| 維護成本 | 高 (改區間改 SQL) | 低 (參數化) |