我的任务是维护一个处理"批次"有"记录"。它们使用InnoDB表存储在MySQL中,log.batch_id
外键将每个批次与其日志链接起来。
我最近不得不优化某些操作的性能,其中一个操作涉及获取批次列表以及每个操作的日志计数。此操作过去实现为LEFT JOIN
按batch.id
分组,但性能不可接受,因此我转换为非规范化状态,每个批次保持cached_log_count
值。
由于应用程序如何处理其业务,此缓存计数仅在每个批次创建后不久更新一次。伪代码如下:
# there are no logs at all for batch id = 42 at this point
$batch = SELECT * FROM batch WHERE id = 42
BEGIN
FOR (EACH LOG)
INSERT INTO log (batch.id, ...) VALUES 42, ...
# error checking elided
END FOR
$logCount = SELECT COUNT(*) FROM log WHERE batch.id = 42
UPDATE batch SET cached_log_count = $logCount WHERE id = 42
COMMIT
我希望以上内容填充log
表格并正确设置相关批次的cached_log_count
,大部分时间确实会发生什么。但是,每隔一段时间我就会得到一个cached_log_count
等于零的批处理(即创建时的初始值是什么),同时日志在数据库中显示就好了。
发生了什么?我不明白以上不可以正确更新日志计数的可能性。我已经考虑过重构一下,以便将SELECT COUNT(*)
/ UPDATE batch
对变成单个UPDATE ... SELECT
,但这看起来并没有帮助。
可能相关的其他信息:
答案 0 :(得分:0)
如果您使用的是MySQL 5.5或5.6 然后可能由于以下原因而发生: