0

我有如下表:我應該使用分區,在這種情況下

CREATE TABLE `connections` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
`user_id_from` int(11) NOT NULL, 
`user_id_to` int(11) NOT NULL, 
`counter` int(11) NOT NULL, 
PRIMARY KEY (`id`), 
UNIQUE KEY `to_from` (`user_id_to`,`user_id_from`), 
KEY `user_id_from` (`user_id_from`) 
) ENGINE=InnoDB AUTO_INCREMENT=1559108041 DEFAULT CHARSET=utf8 

這是103GB(43GB的數據和59GB指數)和大約〜1143663061行。我認爲主要的性能障礙是索引大小的結果,因此解決方案可能意味着將其減小爲小型索引(分區)。我正在考慮添加一個DATE字段,並按月進行分區。每次只能查詢最近的X個月(X將在6左右),我可以忍受。我看到的騙局是這會導致桌子變得比現在更大。

在我測試基準之前,你會推薦這個嗎?你有其他建議嗎?

更新: 我使用這個表的查詢:
SELECT * FROM connections WHERE user_id_to=x LIMIT 3000
SELECT * FROM connections WHERE user_id_from=x ORDER BY counter DESC LIMIT 100
SELECT user_id_from, counter FROM connections WHERE user_id_to IN (x1, x2, ..., x1000) LIMIT 500
SELECT * FROM connections WHERE user_id_to=x AND user_id_from IN (x1, x2, ..., x1000) LIMIT 1000

我通過user_id_to爲主要條件,也user_id_from爲主要查詢的原因條件,是否有連接是有方向性的,並且我正在尋找相互連接(從→到>從& &從 - >到)。 WHERE user_id_to的行數可能會非常高,因爲WHERE user_id_from大多不是那麼多,這就是爲什麼當我ORDER BY counter我沒有爲此添加索引時。

+0

查看下面的答案可能會刪除您的索引之一。另外,奇怪的是你會有'_from'和'_to'和INT字段而不是日期字段。在整個表格中保持它們的獨特性意味着沒有兩個用戶可以有相同的開始和結束日期,這也很奇怪。 – aneroid

+0

_「在我測試基準之前...」 - - 您應該首先對**進行基準測試,並確定確切的查詢速度緩慢(以及它們的計時和執行計劃)。替代鍵「id」是否有[特定原因](http://stackoverflow.com/tags/surrogate-key/info)?如果不是,則可以忽略它,並使用'{user_id_to,user_id_from}'作爲主鍵,從而減少所需的存儲空間。除此之外,我懷疑'{user_id_from,user_id_to}'上的複合索引可能比單獨使用'{user_id_from}'更好。但所有這些都是猜測而不知道你的疑問。 –

+0

@BrankoDimitrijevic有趣的想法刪除代理鍵。它沒有任何特定的原因,但是在某些情況下我發現它們很有用(例如,當想要以塊的形式迭代表格時)。 '{user_id_from,user_id_to}'索引不會比'{user_id_from}'大嗎?你爲什麼懷疑它會爲我提供更好的服務?有關分區選項的任何想法? – Noam

回答

0

你可以通過修改唯一鍵(取決於您的查詢如何使用它們)刪除一個索引user_id_from:與其to_from,使其from_to(user_id_from,user_id_to),像始端。那麼您將不需要0​​上的第二個索引,因爲即使第二部分不是必需的(user_id_to),也可以使用第一部分組合索引/鍵user_id_from

所以你只需要:

PRIMARY KEY (`id`) 
UNIQUE KEY `from_to` (`user_id_from`,`user_id_to`) 

這是一個變化,以節省索引使用的空間。 (使用表的一小部分進行測試,並查看EXPLAIN結果)。 PS:當您繼續進行此更改時,請刪除user_id_*索引,然後創建from_to索引,以防您的磁盤限制超過30 GB。

具體到你的問題...
如果舊的數據將不再需要,它可能更有意義之一:

  1. 刪除舊行,當user_id_to超過1年以前等;或者,
  2. (帶選項1) - 創建一個表,如old_users,只需添加其ID和user_id_to字段,如果您需要該信息。
  3. connections_archive等新表格中插入舊行connections,然後從connections中刪除。假設您在應用程序的查詢中不會查詢_archive,或者只從管理界面(即很少)查詢_archive,在這種情況下,會遇到connectionsconnections_archive的「聯合」查詢性能問題。
+0

我已經更新了這個表格上運行的查詢的問題,如果我錯了,請更正我的錯誤,但我假設您的解決方案不包含像我需要的WHERE user_id_to = x這樣的查詢。 – Noam

+0

你是對的,我以爲你不會有一個只使用'user_id_to'而沒有'user_id_from'的查詢。因此,我建議複合'{user_id_from,user_id_to}'而不是to-from。 Branko的一些評論可能會更好地解決你的問題。 – aneroid

相關問題