2013-03-12 89 views
0

目前,我有一張桌子,它的填充速度非常快。 我有50個設備。我每隔30秒從每臺設備收集數據。因此,在添加10,000個設備之後,他們每個月會產生8.76億條記錄 - 這是很多!數據庫設計 - 如何構造

INSERT INTO unit_data 
(`id`,`dt`,`id_unit`,`data1`,`data2`, 
`ip`,`unique_id`,`loc_age`,`reason_code`, 
`data3`,`data4`,`Odo`,`event_time_gmt_unix`, 
`switches`,`on_off`,`data5`) 

這裏有我的關係

PRIMARY KEY (`id`), 
    UNIQUE KEY `id_unit_data_UNIQUE` `id`), 
    KEY `fk_gp2` (`id_unit`), 
    KEY `unit_dt_id` (`dt`,`id_unit`), 
    KEY `unit_id_dt` (`id_unit`,`dt`), 
    CONSTRAINT `fk_gp2` FOREIGN KEY (`id_unit`) REFERENCES `unit` (`id_unit`) ON DELETE CASCADE ON UPDATE CASCADE 
) ENGINE=InnoDB AUTO_INCREMENT=1049392 DEFAULT CHARSET=utf8$$ 

我現在面臨非常複雜的查詢和報表,當我做這些,我們的系統沒有響應,並擊中執行超時。 (這是2mil +記錄)

我需要重新考慮並重新實現數據庫結構。目前我正在考慮要麼

  • 每個單元
  • 各單位每月

,你有什麼建議創建新表創建新表?

+0

單位=設備,對吧?我不會建議爲每個設備創建一個單獨的表。您的索引是否可以解決您必須運行的查詢? – Melanie 2013-03-12 16:29:15

+0

長時間運行的查詢是什麼樣的? – 2013-03-12 17:04:59

+0

Darius,我目前也試圖修復查詢:http://stackoverflow.com/questions/15367719 – Andrew 2013-03-12 17:19:45

回答

0

創建新表是一個不錯的主意,但您不需要實現它,MySql已經有了關於「mysql +分區」關鍵字的工具 - 谷歌。我建議使用它,因爲你不需要改變你的查詢,mysql本身就關心它。只需將「partition by」關鍵字添加到您創建的表格中即可。

對你來說還有一個竅門:我建議你將大量信息收集到一些大表中,並且有時還要從中選擇一些數據。但插入許多新行會引發表被鎖定(不可用於選擇)和重建索引(我確信您的表已編入索引)。在我目前的項目中,我正在做類似於你的事情,我建議你做以下事情:

1)創建BIG-TABLE的表格克隆。它應該與BIG-TABLE具有相同的結構,但有一點不同 - 表 - 克隆沒有索引。

2)當您從設備接收數據時,將其放入表格克隆中。

3)寫一些機器人代理,它會將小表中的記錄每小時或每天都放入大表中 - 這取決於您,但最好的情況是選擇表格大小足以進行全屏掃描的間隔(請記住,它沒有編入索引)。 4)當你想要執行SELECT查詢時,你需要在2個表格中執行 - 在索引BIG表格中 - 足夠快,因爲沒有人試圖插入數據(有時只有機器人會這樣做),而fullscan在小表格中 - 也足夠快,因爲你可以保持它很小。

5)機器人應該在平靜的時間醒來c-可能是在晚上。

+0

我已經有一個表格顯示最新記錄,而這張大表格用於報告。所以當我運行我的報告時,我的服務器在cpu中達到100%所有客戶端都遭受了30秒的困擾 – Andrew 2013-03-17 18:25:46

+0

您的意思是報告時間與從小表到大表插入新鮮最新記錄相吻合?因爲這種情況似乎是唯一的不好的情況。可能是你應該存儲大表的2副本 - BT1,BT2;將最新記錄寫入BT1每個「some_interval」小時,刪除prev BT2並將其替換爲BT1的新副本。運行BT2報告。這種結構可以保證您的報告(選擇)/填充(插入)查詢不會相交。 – Baurzhan 2013-03-18 02:55:54