gpt4 book ai didi

mysql - 为什么 InnoDB 无法正确读取或写入计数?

转载 作者:行者123 更新时间:2023-11-30 00:25:38 25 4
gpt4 key购买 nike

我的任务是维护一个处理具有“日志”的“批处理”的应用程序。这些数据使用 InnoDB 表存储在 MySQL 中,并使用 log.batch_id 外键将每个批处理与其日志链接起来。

我最近必须优化某些操作的性能,其中之一涉及获取批处理列表以及每个批处理的日志计数。此操作过去被实现为按 batch.id 分组的 LEFT JOIN,但性能 Not Acceptable ,因此我转换为保留 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 等于 0 的批处理(即创建时的初始值),同时日志在数据库中显示得很好。

发生什么事了?我不明白上面的内容怎么可能总是正确更新日志计数。我考虑过进行一些重构,以便将 SELECT COUNT(*)/UPDATE batch 对转换为单个 UPDATE ... SELECT,但这看起来没有帮助。

可能相关的其他信息:

  • 有效的事务隔离级别是 REPEATABLE READ。
  • 该问题似乎仅在具有数千个日志的批处理中出现,但即使如此,也很少发生。

最佳答案

如果您使用的是 MySQL 5.5 或 5.6那么出现这种情况可能是由于以下原因:

  • 在某些情况下,优化器可能会优化掉用户定义的变量,从而阻止它们执行您想要的操作。
  • 分配的顺序,甚至分配的时间,都可能是不确定的,并且取决于优化器选择的查询计划。结果可能会非常令人困惑,稍后您将会看到。
  • := 赋值运算符的优先级低于任何其他运算符,因此必须小心地显式添加括号。

关于mysql - 为什么 InnoDB 无法正确读取或写入计数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22911808/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com