处理删除/插入/选择一个巨大的表格

时间:2013-05-20 09:10:48

标签: mysql mysql5 mysql-5.1 mysql-5.5

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

SENDER RECEIVER
11      1
12      1
13      1
14      1

我保持两个月的日志。 用户也可以登录我的网站查看它们。

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

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

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

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

4 个答案:

答案 0 :(得分:3)

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

MERGE是一种很少或永远不会改变的表格的解决方案:MERGE Table Advantages and Disadvantages

您有两个选择:

尽量减少锁定的影响:

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

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

  • 从每个基础表中删除几个要删除的语句
  • 删除MERGE定义,从每个基础表中删除数据创建MERGE。但是,我认为你可以在不删除MERGE定义的情况下完成它。
  • 使用分区。

来自MySQL手册:

  

MERGE表的替代方法是存储分区表   单个表中的分区在单独的文件中。分区启用   一些操作要更有效地执行,并不限于此   MyISAM存储引擎。有关详细信息,请参阅Chapter 18, Partitioning

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

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

答案 1 :(得分:1)

我认为最好的解决方案是根据用户ID在日志上设置partitions。这样当你运行删除时,Db将只阻止一个分区。

答案 2 :(得分:1)

如果你谷歌“在巨大的桌面上删除”,你将获得一些信息性的结果。以下是前三个点击:

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

Improving DELETE and INSERT times on a large table that has an index structure

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

他们都提到的一种方法是小批量删除,而不是一次性删除。你说该表包含2个月的数据。也许你每天都分开运行删除语句?

我希望这有帮助!

答案 3 :(得分:0)

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

CREATE TABLE `DailyChoices`(

sender INT(11)NOT NULL, receiver INT(11)NOT NULL, CONSTRAINT FOREIGN KEY(sender)REFERENCES usersuserid)ON更新级联上的DELCAD CASCADE )TYPE = InnoDB;