繁体   English   中英

在这种情况下我应该使用分区吗

[英]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。

专门针对您的问题...
如果不需要旧数据,则可能更有意义:

  1. 删除旧行,例如user_id_to超过1年之前; 要么,
  2. (带有选项1)-创建一个表,如old_users ,如果需要该信息,只需添加其ID和user_id_to字段。
  3. connections旧行插入到新表(如connections_archive ,然后从connections删除。 假设您永远不会在应用程序的查询中查询_archive ,或者仅从管理界面查询(即很少),在这种情况下,具有connectionsconnections_archive的“联合”查询的性能下降将是可以承受的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM