Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql更新性能突然变得糟糕透了_Mysql_Ubuntu 10.10 - Fatal编程技术网

Mysql更新性能突然变得糟糕透了

Mysql更新性能突然变得糟糕透了,mysql,ubuntu-10.10,Mysql,Ubuntu 10.10,MySQL 5.1,Ubuntu 10.10 64位,Linode虚拟机 所有表都是InnoDB 我们的一台生产机器使用包含31个相关表的MySQL数据库。在一个表中,有一个包含显示值的字段,根据条件,显示值每天可能更改数次 这些对显示值的更改在一天中的使用时间内缓慢应用。脚本定期运行并检查一些可能导致更改的条件,并在满足条件时更新显示值。但是,这种延迟方法并不能捕获所有可能的场景,在这些场景中,显示值应该更新,以便在工作时间内将后台进程负载保持在最小 每晚一次,脚本清除存储在表中的所有显示值并

MySQL 5.1,Ubuntu 10.10 64位,Linode虚拟机

所有表都是InnoDB

我们的一台生产机器使用包含31个相关表的MySQL数据库。在一个表中,有一个包含显示值的字段,根据条件,显示值每天可能更改数次

这些对显示值的更改在一天中的使用时间内缓慢应用。脚本定期运行并检查一些可能导致更改的条件,并在满足条件时更新显示值。但是,这种延迟方法并不能捕获所有可能的场景,在这些场景中,显示值应该更新,以便在工作时间内将后台进程负载保持在最小

每晚一次,脚本清除存储在表中的所有显示值并重新计算它们,从而捕获所有可能的更改。这是一个更昂贵的操作

这一切已经持续运行了大约6个月。三天前,夜间脚本的运行时间突然从平均40秒增加到11分钟

存储数据的总体比例没有显著变化

我已经尽我所能进行了调查,脚本中突然运行较慢的部分是写入新显示值的最后一条update语句。给定行的(INT(11))id和新的显示值(也是INT),每行执行一次

有趣的是,清除所有以前的值的过程如下所示:

update `table` set `display_value` = null
这句话的速度仍然和往常一样

显示值
字段未编制索引<代码>id是主键。
中还有4个外键在执行过程中任何时候都不会被修改

最后一个曲线球:如果我将此模式转储到测试VM,并执行相同的脚本,它将在40秒而不是11分钟内运行。我没有尝试在生产机器上重建模式,因为这不是一个长期的解决方案,我想了解这里发生了什么

我的索引有问题吗?在同一行上进行了数千次更新后,它们是否变得粗糙


更新

通过在模式上运行优化,我能够完全解决这个问题。由于InnoDB不支持optimize,因此强制进行了重建,并解决了问题。也许我的索引被破坏了

mysqlcheck -A -o -u <user> -p
mysqlcheck-A-o-u-p

有可能
UPDATE
语句不会在
id
上使用索引,但是,对于像您这样的查询,这是非常不可能的(如果可能的话)

您的表是否有可能被长时间运行的并发查询/
DML
锁定?桌子使用哪种引擎

此外,逐个记录更新表记录也没有效率。您可以批量将值加载到临时表中,并使用单个命令更新主表:

CREATE TEMPORARY TABLE tmp_display_values (id INT NOT NULL PRIMARY KEY, new_display_value INT);

INSERT
INTO    tmp_display_values
VALUES
(?, ?),
(?, ?),
…;

UPDATE  `table` dv
JOIN    tmp_display_values t
ON      dv.id = t.id
SET     dv.new_display_value = t.new_display_value;

谢谢你的回复。所有表都是InnoDB。在执行时,不应运行其他查询。我们的客户群都处于休眠状态,没有其他自动化流程在运行。我知道效率低下,直到现在才考虑到这一点。我能够通过重建模式来解决问题,但您关于性能的观点仍然完全有效,因此我将您的回答标记为解决方案。谢谢经过周末的进一步测试,我一直无法找出突然的变化。与以前的历史相比,此脚本的执行时间仍然太长。我甚至完全重启了生产机器。
CREATE TEMPORARY TABLE tmp_display_values (id INT NOT NULL PRIMARY KEY, new_display_value INT);

INSERT
INTO    tmp_display_values
VALUES
(?, ?),
(?, ?),
…;

UPDATE  `table` dv
JOIN    tmp_display_values t
ON      dv.id = t.id
SET     dv.new_display_value = t.new_display_value;