3

我有一个约会网站。在这个网站上,我曾经每天向用户发送 10 张照片匹配并将它们存储在结构中

SENDER RECEIVER
11      1
12      1
13      1
14      1

我维护两个月的日志。用户也可以通过登录我的网站来查看它们。

这意味着存在并行插入和选择,这肯定不是问题。

问题是当用户变为非活动状态或删除其 ID 时,我需要从日志中删除 sender='inactive-id' 的所有条目。

日志大小约为 6000 万。因此,每当删除查询出现在这个巨大的表中时,所有选择都会被锁定,我的网站就会关闭。

请注意,我的表是合并 myisam,因为我需要存储 2-3 个月的记录,并且每个月的第一天我都会更改定义

4

4 回答 4

3

通常,Table 是被 DELETE 语句锁定的最细粒度的对象。因此,通过使用 MERGE 表,您可以将多个可以独立锁定的对象组合成一个大对象,当 DELETE 命中其任何表时,该对象将被锁定。

MERGE 是针对很少或从不更改的表的解决方案:MERGE Table 的优点和缺点

您有 2 个选项:

最小化锁的影响:

  • 小批量删除
  • 在低负载时间运行删除作业
  • 考虑根本不删除,如果它不能为您节省太多空间
  • 而不是删除行将它们标记为“已删除”或已过时并从 SELECT 查询中排除

锁定较小的对象(而不是一次锁定所有表):

  • 有几个 Delete 语句要从每个基础表中删除
  • 删除 MERGE 定义,从创建 MERGE 的每个基础表中删除数据。但是,我认为您可以在不放弃 MERGE 定义的情况下做到这一点。
  • 使用分区。

引用自 MySQL 手册:

MERGE 表的替代方案是分区表,它将单个表的分区存储在单独的文件中。分区可以更高效地执行某些操作,并且不限于 MyISAM 存储引擎。有关详细信息,请参阅第 18 章,分区

我强烈主张分区,因为: - 您可以完全自动化您的日志记录/数据保留过程:脚本可以创建新分区并删除空分区,将过时的数据移动到不同的表,然后截断该表。- 强制执行密钥唯一性 - 仅锁定包含要删除的数据的分区。其他分区上的选择正常运行。- 搜索同时在所有分区上运行(与 MERGE 一样),但您可以使用 HASH SubPartitioning 来进一步加快搜索速度。

但是,如果您认为分区的好处将超过开发成本,那么您可能根本不应该删除这些数据吗?

于 2013-05-23T09:35:44.893 回答
1

我认为最好的解决方案是根据用户 ID 在日志上设置分区。这样,当您运行 delete Db 时,只会阻塞一个分区。

于 2013-05-22T09:41:59.077 回答
1

如果你用谷歌搜索“在大桌子上删除”,你会得到一些信息丰富的结果。以下是前三个热门:

http://www.dba-oracle.com/t_oracle_fastest_delete_from_large_table.htm

在具有索引结构的大表上改进 DELETE 和 INSERT 时间

http://www.dbforums.com/microsoft-sql-server/1635228-fastest-way-delete-large-table.html

他们都提到的一种方法是小批量删除,而不是一次全部删除。您说该表包含 2 个月期间的数据。也许您每天单独运行删除语句?

我希望这有帮助!

于 2013-05-22T09:49:06.327 回答
0

如果您使用 InnoDB 并创建 FOREIGN KEY 关系,则可以在删除用户自己时自动删除行:

CREATE TABLE `DailyChoices`(

senderINT(11) NOT NULL, receiverINT(11) NOT NULL, 约束外键 ( sender) 引用users( userid) ON DELETE CASCADE ON UPDATE CASCADE) TYPE = InnoDB;

于 2013-05-29T09:05:30.100 回答