[英]Should I use partitions in this case
我有下表:
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索引)和约1,143,663,061行。 我认为主要的性能障碍是索引大小的结果,因此该解决方案可能意味着将其缩减为较小的索引(分区)。 我正在考虑添加DATE字段并在MONTH之前进行分区。 我可以忍受每次只查询最近的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作为主要条件来查询的原因是,连接是定向的,并且我正在寻找相互连接(to-> from && from-> to)。 WHERE user_id_to
的行数可能非常多,而WHERE user_id_from
却没有那么多,这就是为什么当我ORDER BY counter
我没有为此添加索引的原因。
您可以通过修改唯一键(取决于查询的使用方式)来删除一个索引user_id_from
:与to_from
,将其from_to
为(user_id_from,user_id_to)
,如start-end 。 然后,您将不需要user_id_from
上的第二个索引,因为即使不需要第二部分( 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
索引,以防您的磁盘空间from_to
30 GB。
专门针对您的问题...
如果不需要旧数据,则可能更有意义:
user_id_to
超过1年之前; 要么, old_users
,如果需要该信息,只需添加其ID和user_id_to
字段。 connections
旧行插入到新表(如connections_archive
,然后从connections
删除。 假设您永远不会在应用程序的查询中查询_archive
,或者仅从管理界面查询(即很少),在这种情况下,具有connections
和connections_archive
的“联合”查询的性能下降将是可以承受的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.