我看過這個問題幾乎在一些線程上回答,但沒有考慮到對這個特定域的影響:多個表或使用分區?
我期待在MySQL中存儲大量儀表的時間序列數據(500和增長),它們每隔5分鐘提供一次浮動值。在最簡單的,該結構將是: - gauge_id - 時間戳 - 值
(其中gauge_id和時間戳結合作爲主鍵)
這意味着每計大約每年105120行 - 所有這些都需要儲存10年或20年。對於1000臺儀表,我們每年會看1億條記錄。
數據是批量寫入的,每個通道的值通常會彙總到來自遠程源的XML文件中,並每小時或每天讀入數據庫。因此,最多隻能有一個小時的插入件數量與我們的量表一樣多。
基於時間範圍,數據的讀操作將按照量表進行(所以不需要在量表之間進行數據連接操作)。所以例如在兩個日期之間獲得量表X的所有值。 通常,這還包括某種形式的聚合/插值函數 - 因此用戶可能希望查看每日平均值或每週最大值等,以查看任意範圍。 同樣,讀取次數相對較少,但這些需要MySQL在1秒內做出響應。
在這個階段,我對每個量表的1個表進行了標準化,而不是在gauge_id上對MySQL中的一個巨大表進行分區。 這樣做的邏輯將使分片更容易,簡化備份,並且本質上使得如果在任何階段存在數據錯誤,則量表更容易移除/重建。 成本是寫入和讀取operatiosn都稍微複雜一點。
對此有何看法?
-------- -------- UPDATE
我跑我的MacBook 2.4GHz的Core 2 Duo處理器,RAM的4場音樂會一些測試。
設置如下表:
CREATE TABLE `test` (
`channel_id` int(10) NOT NULL,
`time` datetime NOT NULL,
`value` int(10) NOT NULL,
KEY `channel_id` (`channel_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
與存儲過程填充的:
CREATE PROCEDURE `addTestData`(IN ID INT, IN RECORDS INT)
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE j DATETIME DEFAULT '1970-01-01 00:00:00';
WHILE (i<=RECORDS) DO
INSERT INTO test VALUES(ID,j,999);
SET i=i+1;
SET j= j + INTERVAL 15 MINUTE;
END WHILE;
END $$
,而我則叫創建第一個100萬條記錄
call addTestData(1,1000000);
插入在執行47秒
SELECT * FROM `test` WHERE channel_id = 1 and YEAR(time) = '1970';
在0.0006秒
SELECT AVG(value) as value, DATE(time) as date FROM `test`
WHERE channel_id = 1 and YEAR(time) = '1970' group by date;
在4.6秒(MAX,在同一時間執行SUM函數)執行的處理。
加入4個計後:
call addTestData(2,1000000);
call addTestData(3,1000000);
call addTestData(4,1000000);
call addTestData(5,1000000);
插入件在47秒執行的每個中,用於表
78兆字節我跑的相同的兩個查詢 - 並得到完全相同的執行時間與表中有100萬條記錄(更大的查詢爲4.6秒)。因此,禁止分片,備份和未來硬件驅動的變更對任何單個量表的表格(即多個讀數,數據間隔的變化)的潛在用途,似乎沒有必要爲可預見的分割成多個表格。甚至沒有嘗試用分區運行查詢,似乎沒有任何理由。
--------無論其-------------
由於4.6秒一個查詢是不理想的,我們顯然需要做一些優化。 作爲第一步,我重新調整了查詢:5萬條記錄(超過5 CHANNEL_ID的)的查詢需要4.3秒桌子上
SELECT
AVG(value) as value,
DATE(time) as date
FROM
(SELECT * FROM test
WHERE channel_id = 1 and YEAR(time) = '1970')
as temp
group by date;
運行。 如果我在1通道,100萬條記錄的桌子上運行它,它會在0.36秒內運行! 抓我的頭有點過這...
分區的500萬條記錄
ALTER TABLE test PARTITION BY HASH(channel_id) PARTITIONS 5;
表隨後完成了複合查詢以上0.35秒也同樣的性能增益。
單個表(5億行)將如何執行: – Rean
單個表(5億行)如何在一年內相隔兩年的兩個日期之間用選擇查詢在gauge_id上執行,AND要求結果成爲AVG一年中每個月的團體數量? (與僅有一個量表的500萬條記錄表上的同一查詢相比,可能劃分爲'最近'和'歸檔') – Rean
只需添加 - 我也考慮管理5億行單個表的含義。我有預感,重建索引的任何東西都會很昂貴。或者例如一個批量更新查詢,其中一個量表被發現已經提供了6個月的誤校準值。 – Rean