0

请从能够抽出时间的 Super Guru MySQL/PHP 专业人士那里寻求一些帮助和建议。

我有一个 PHP/MySQL 的 web 应用程序,它多年来一直在增长,并且得到了很多搜索。现在,当使用 MySQL LOAD DATA INFILE 处理新行的各种日常数据转储时,它会遇到瓶颈。

它是一个包含大约 150 万行的大型 MyISAM 表,所有 SELECT 查询都发生在它上面。当这些发生在大约 600k 行的 LOAD DATA INFILE 期间(并删除过时的数据)时,它们只会被备份并需要大约 30 分钟以上的时间才能释放,从而使这些搜索中的任何一个都没有结果。

我需要想出一种方法来更新该表,同时保留在合理的时间范围内提供 SELECT 结果的能力。

我完全没有想法,也无法自己想出解决方案,因为这是我第一次遇到此类问题。

任何有用的建议、解决方案或类似过去经验的指示将不胜感激,因为我很想学习解决这类问题。

非常感谢大家的时间!Ĵ

4

3 回答 3

1

您可以对 LOAD DATA INFILE 使用 CONCURRENT 关键字。这样,当您加载数据时,该表仍然能够为 SELECT 服务。

关于删除,这更复杂。我会亲自添加一个名为'status' INT(1) 的列,该列将定义该行是否处于活动状态(= 已删除),然后使用基于此列状态的规则对我的表进行分区。

这样,删除 status=0 的所有行会更容易:PI 还没有测试过最后一个解决方案,我可能会在不久的将来这样做。

如果您的表已优化,则 CONCURRENT 关键字将起作用。如果有任何 FREE_SPACE,则 LOAD DATA INFILE 将锁定该表。

于 2011-09-06T09:34:35.130 回答
0

MyISAM 不支持行级锁定,因此 mysqldump 之类的操作被迫锁定整个表以保证一致的转储。您唯一实用的选择是切换到另一个支持行级锁定的表(如 InnoDB),和/或将转储拆分为更小的部分。小型转储在转储/重新加载时仍会锁定表,但锁定周期会更短。

一个更复杂的选择是拥有“实时”和“备份”表。对备份表执行转储/加载操作。当它们完成时,将其换成活动表(重命名表,或者让您的代码动态更改它们正在使用的表)。如果您可以忍受一小段潜在陈旧数据的窗口,这可能会更好选项。

于 2011-02-21T23:02:08.043 回答
0

您应该将表存储引擎从 MyISAM 切换到 InnoDB。InnoDB 提供行锁定(与 MyISAM 的表锁定相反)意味着当一个查询忙于更新或插入一行时,另一个查询可以同时更新不同的行。

于 2011-02-21T23:03:52.100 回答