【发布时间】:2010-09-06 04:16:34
【问题描述】:
有关背景信息,请参阅this previous question。我正在尝试使用 SQL 重新编号损坏的 MPTT 树。该脚本在逻辑上运行良好,只是太慢了。
我反复需要执行这两个查询:
UPDATE `tree`
SET `rght` = `rght` + 2
WHERE `rght` > currentLeft;
UPDATE `tree`
SET `lft` = `lft` + 2
WHERE `lft` > currentLeft;
表是这样定义的:
CREATE TABLE `tree` (
`id` char(36) NOT NULL DEFAULT '',
`parent_id` char(36) DEFAULT NULL,
`lft` int(11) unsigned DEFAULT NULL,
`rght` int(11) unsigned DEFAULT NULL,
... (a couple of more columns) ...,
PRIMARY KEY (`id`),
KEY `parent_id` (`parent_id`),
KEY `lft` (`lft`),
KEY `rght` (`rght`),
... (a few more indexes) ...
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
数据库是 MySQL 5.1.37。表中目前有约 120,000 条记录。两个UPDATE 查询中的每一个都需要大约 15 - 20 秒来执行。 WHERE 条件可能适用于大多数记录,因此几乎所有记录每次都需要更新。在最坏的情况下,两个查询的执行次数与数据库中的记录一样多。
有没有办法通过将值保存在内存中、延迟写入磁盘、延迟索引更新或类似的方式来优化此查询?现在的瓶颈似乎是硬盘吞吐量,因为 MySQL 似乎正在立即将所有内容写回磁盘。
任何建议表示赞赏。
【问题讨论】:
-
一些想法:降低/消除 ACID 隔离级别。删除索引并在完成后添加,锁定表。将一大块更新包装到一个事务中。转换为 MyISAM 然后再转换回来。
-
@Rob 如果您能扩展您的回答,特别是降低隔离级别的具体步骤,我会很高兴。 :)
标签: mysql optimization