業務常需按固定時間窗口(如每 5 分鐘、每半小時、每小時)聚合統計。MySQL 利用時間戳數學運算構造分組鍵,配合索引可高效完成。本文提供兩種核心實現方式、索引建議、大數據量優化方案。
CREATE TABLE `instance` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`timestamp` INT UNSIGNED DEFAULT NULL, -- Unix 時間戳
`cpu` DECIMAL(8,3) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_timestamp` (`timestamp`)
) ENGINE=InnoDB;
-- 每 5 分鐘 (300 秒) 平均值 SELECT `timestamp` - `timestamp` % 300 AS time_bucket, AVG(`cpu`) AS avg_cpu FROM `instance` GROUP BY time_bucket ORDER BY time_bucket;
原理: 同一時間窗口內的時間戳對窗口秒數取模結果相同,作為分組鍵。
-- 每半小時統計
SELECT
queueName,
HOUR(`dt`) AS h,
FLOOR(MINUTE(`dt`) / 30) AS v,
AVG(memoryUsed) AS avg_mem,
SUM(memoryUsed) AS sum_mem,
COUNT(*) AS cnt
FROM queue_resource
WHERE `dt` >= '2014-04-14 00:00:00'
GROUP BY queueName, h, v
ORDER BY queueName, h, v;
適用: DATETIME/TIMESTAMP 型別欄位,業務邏輯清晰。
KEY idx_timestamp (timestamp) — 適用方法 1,掃描索引即可完成分組。KEY idx_dt_queue (dt, queueName, memoryUsed) — 適用方法 2,實現索引覆蓋,避免回表。timestamp RANGE 分區(如按月),配合分區裁剪大幅減少掃描範圍。| 方案 | 原理 | 適用場景 |
|---|---|---|
| 物化視圖/摘要表 | 定時任務預聚合寫入摘要表,查詢直接讀摘要 | 高頻儀表盤、報表 |
| ClickHouse/Apache Doris | OLAP 列式引擎,原生支援時間窗口聚合 | 億級+ 時序數據分析 |
| Redis 滑動窗口 | 寫入時同步更新 Redis Sorted Set/Hash,毫秒級讀取 | 實時大屏、告警 |
| 分區 + 並行查詢 | MySQL 8.0+ 支援並行掃描分區 | 遷移成本低、資料量百萬級 |
timestamp 存儲為 UTC,應用層統一處理時區轉換。WHERE dt >= '2024-01-01' AND dt < '2024-01-02' 避免跨日重複/遺漏。COUNT(*) 計入 NULL 行,COUNT(col) 不計入。FLOAT/DOUBLE 聚合有精度誤差,金額/關鍵指標用 DECIMAL。時間窗口分組統計核心是「構造確定性分組鍵」。Unix 時間戳取模效能最優,日期函數可讀性最佳。配合覆蓋索引、分區表、摘要表分層架構,可支撐從萬級到億級的時序聚合查詢需求。