Long 运行 SELECT with UPDATE 锁定数据库

Long running SELECT with UPDATE locks database

我有一个 select 语句需要很长时间才能达到 运行(大约 5 分钟)。因此我每小时只 运行 查询并将结果保存到元数据 table。这是查询:

UPDATE `metadata` SET `value` = (select count(`id`) from `logs`) WHERE `key` = 'logs'

但这是我一直遇到的问题(如果我错了请纠正我)。 select 语句不会锁定数据库,但更新语句会。现在,由于我在更新查询中 运行 宁这个长破坏性 select 查询,它最终锁定数据库大约 5 分钟。

是否有更好的方法来对 运行 select 语句执行此操作并将其保存到变量中,然后在完成后 运行 更新查询?这样它就不会锁定数据库。

另请注意,我不关心脏数据。

数据库有超过 3 亿行,并且数据不断添加。

只是为了避免服务器在获取计数的语句和存储它的语句之间断开连接的可能性,从而使您的变量未设置,从 mariadb 1.1 开始,您可以 运行 在单个请求中添加多个语句,方法是将他们在一个街区:

begin not atomic
    declare `logs_count` int;
    select count(*) into `logs_count` from `logs`;
    update `metadata` set `value`=`logs_count` where `key`='logs';
end

fiddle

我发现在查询运行之前设置此项似乎有效并且运行速度要快得多。这应该可以防止数据库在执行查询时锁定。然后我们在完成后启用锁定。 (如有不妥之处请指正)

BEGIN
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
UPDATE `metadata` SET `value` = (select count(`id`) from `logs`) WHERE `key` = 'logs';
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
END