Mysql 使用longblobs更新表太慢
我有一个充满数据的表格(大约20000条记录)。我试图用另一个表中的数据来更新它,但是我有一个超时(30秒)。 起初,我尝试了一个简单的解决方案:Mysql 使用longblobs更新表太慢,mysql,blob,Mysql,Blob,我有一个充满数据的表格(大约20000条记录)。我试图用另一个表中的数据来更新它,但是我有一个超时(30秒)。 起初,我尝试了一个简单的解决方案: UPDATE TableWhithBlobs a JOIN AnotherTable b on a.AnotherTableId = b.Id SET a.SomeText= b.Description; 此脚本的工作时间比30秒长得多,因此我尝试减少join: UPDATE TableWhithBlobs a SET a.SomeText = (
UPDATE TableWhithBlobs a
JOIN AnotherTable b on a.AnotherTableId = b.Id
SET a.SomeText= b.Description;
此脚本的工作时间比30秒长得多,因此我尝试减少join:
UPDATE TableWhithBlobs a
SET a.SomeText = (select b.Description from AnotherTable b where a.AnotherTableId = b.Id);
但是这个还是很慢。有没有什么案例可以说明它的速度有多快
编辑:
给我解释一下我在做什么。以前,我有两个表,在我的脚本中称为
TableWhithBlobs
和AnotherTable
。在tableTableWhithBlobs
中,存储了指向tableAnotherTable
的链接,但该链接不是真正的外键,它只是tableAnotherTable
中的一个guid
。对于此guid
,在TableWhithBlobs
中有此引用的唯一键约束。我决定修复这个问题,从表TableWhithBlobs
中删除旧字段,并向其添加一个普通外键(使用另一个表中的主ID
)。问题中的脚本只是将正确的数据添加到此新字段。之后,我删除了旧的guid
引用,并添加了一个新的外键约束。在表whithblobs
中的少量数据中,一切都可以正常工作,但在具有20000行的QA数据库中,速度非常慢
更新
显示创建表的表格whithblobs
CREATE TABLE `TableWhithBlobs` (
`Id` bigint(20) NOT NULL AUTO_INCREMENT,
`AnotherTableId` char(36) CHARACTER SET ascii NOT NULL,
`ChunkNumber` bigint(20) NOT NULL,
`Content` longblob NOT NULL,
`SomeText` bigint(20) NOT NULL,
PRIMARY KEY (`Id`),
UNIQUE KEY `AnotherTableId` (`AnotherTableId`,`ChunkNumber`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
显示创建表和另一个表
CREATE TABLE `AnotherTable` (
`Description` bigint(20) NOT NULL AUTO_INCREMENT,
`Id` char(36) CHARACTER SET ascii NOT NULL,
`Length` bigint(20) NOT NULL,
`ContentDigest` char(68) CHARACTER SET ascii NOT NULL,
`ContentAndMetadataDigest` char(68) CHARACTER SET ascii NOT NULL,
`Status` smallint(6) NOT NULL,
`ChunkStartNumber` bigint(20) NOT NULL DEFAULT '0',
`IsTestData` bit(1) NOT NULL DEFAULT b'0',
PRIMARY KEY (`Description`),
UNIQUE KEY `Id` (`Id`),
UNIQUE KEY `ContentAndMetadataDigest` (`ContentAndMetadataDigest`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
另外,列名可能看起来很奇怪,因为我想隐藏实际的生产方案名称
innodb_缓冲区_池_大小为134217728,RAM为4Gb
结果
explain UPDATE TableWhithBlobs a JOIN AnotherTable b on a.AnotherTableId =
b.Id SET a.SomeText= b.Description;
版本:mysql版本14.14发行版5.7.21-20,适用于使用6.3的debian linux gnu(x86_64),如何进行较小的更新
UPDATE TableWhithBlobs a
JOIN AnotherTable b on a.AnotherTableId = b.Id
SET a.SomeText= b.Description
WHERE a.SomeText <> b.Description;
更新表,其中包含一个
在a上连接另一个表b。另一个表Id=b.Id
设置a.SomeText=b.说明
其中a.SomeText b.描述;
甚至:
UPDATE TableWhithBlobs a
JOIN AnotherTable b on a.AnotherTableId = b.Id
SET a.SomeText= b.Description
WHERE a.SomeText <> b.Description
LIMIT 100;
更新表,其中包含一个
在a上连接另一个表b。另一个表Id=b.Id
设置a.SomeText=b.说明
其中a.SomeText b.描述
上限为100;
您的超时问题应该得到解决进行较小的更新怎么样
UPDATE TableWhithBlobs a
JOIN AnotherTable b on a.AnotherTableId = b.Id
SET a.SomeText= b.Description
WHERE a.SomeText <> b.Description;
更新表,其中包含一个
在a上连接另一个表b。另一个表Id=b.Id
设置a.SomeText=b.说明
其中a.SomeText b.描述;
甚至:
UPDATE TableWhithBlobs a
JOIN AnotherTable b on a.AnotherTableId = b.Id
SET a.SomeText= b.Description
WHERE a.SomeText <> b.Description
LIMIT 100;
更新表,其中包含一个
在a上连接另一个表b。另一个表Id=b.Id
设置a.SomeText=b.说明
其中a.SomeText b.描述
上限为100;
你的超时问题应该得到解决一些想法,其中没有一个会跳出来作为“答案”:
- 将
增加到innodb\u buffer\u pool\u size
,假设这不会导致交换1500M
- 退一步看“为什么”
需要经常复制。以及“所有”行是否需要更新BIGINT
- 将
与当前表并行放入另一个表中。这将为需要获取blob的情况添加一个LONGBLOB
,但可能会使它不妨碍当前查询。(我不希望这一团“碍事”,但显然是这样。)JOIN
- 这团是什么?在某些情况下,最好将blob保存在文件中。一个主要的例子是一个网站的图像——它可以通过http的
访问 - 增加超时时间——但这只会“掩盖问题”,并可能导致等待它的其他事情延迟30秒以上。我不认为30秒是超时时间。查看
显示变量,如“%out”代码>尝试增加30
- 更新是零碎的——但这会有其他影响吗?(无论如何,Luuk应该继续执行此选项。)
- 将
增加到innodb\u buffer\u pool\u size
,假设这不会导致交换1500M
- 退一步看“为什么”
需要经常复制。以及“所有”行是否需要更新BIGINT
- 将
与当前表并行放入另一个表中。这将为需要获取blob的情况添加一个LONGBLOB
,但可能会使它不妨碍当前查询。(我不希望这一团“碍事”,但显然是这样。)JOIN
- 这团是什么?在某些情况下,最好将blob保存在文件中。一个主要的例子是一个网站的图像——它可以通过http的
访问 - 增加超时时间——但这只会“掩盖问题”,并可能导致等待它的其他事情延迟30秒以上。我不认为30秒是超时时间。查看
显示变量,如“%out”代码>尝试增加30
- 更新是零碎的——但这会有其他影响吗?(无论如何,Luuk应该继续执行此选项。)
tablewhithblob
有两个(或更多)id=1,而另一个表也有两个(或更多)id=1..@tcadidot0 TableWhithBlobs.AnotherTableId和AnotherTable.id是唯一的我对此不太确定,但是除了现有的主键之外,您是否为这两列添加了另一个索引?@tcadidot0我想我应该解释一下我在做什么。以前,我有两个表,在我的脚本中称为TableWhithBlobs和AnotherTable。在TableWhithBlobs表中,存储了指向另一个表的链接,但该链接不是真正的外键,它只是来自另一个表的guid。对于此guid,TableWhithBlobs中的此引用有一个唯一的键约束。我决定修复这个问题,从TableWhithBlobs表中删除旧字段,并向其添加一个普通外键(使用另一个表中的主ID)