我有如下表:我应该使用分区,在这种情况下
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
我没有为此添加索引时。
查看下面的答案可能会删除您的索引之一。另外,奇怪的是你会有'_from'和'_to'和INT字段而不是日期字段。在整个表格中保持它们的独特性意味着没有两个用户可以有相同的开始和结束日期,这也很奇怪。 – aneroid
_“在我测试基准之前...” - - 您应该首先对**进行基准测试,并确定确切的查询速度缓慢(以及它们的计时和执行计划)。替代键“id”是否有[特定原因](http://stackoverflow.com/tags/surrogate-key/info)?如果不是,则可以忽略它,并使用'{user_id_to,user_id_from}'作为主键,从而减少所需的存储空间。除此之外,我怀疑'{user_id_from,user_id_to}'上的复合索引可能比单独使用'{user_id_from}'更好。但所有这些都是猜测而不知道你的疑问。 –
@BrankoDimitrijevic有趣的想法删除代理键。它没有任何特定的原因,但是在某些情况下我发现它们很有用(例如,当想要以块的形式迭代表格时)。 '{user_id_from,user_id_to}'索引不会比'{user_id_from}'大吗?你为什么怀疑它会为我提供更好的服务?有关分区选项的任何想法? – Noam