如何减少命中分贝倍数

How to reduce hitting db multiple

假设我有十万用户

简单示例,

user = User.where(id: 1..10000)

User Load (30.8ms)  SELECT `users`.* FROM `users`  WHERE (`users`.`id` BETWEEN 1 AND 10000)

在这里,我想像这样切片,

user.where(id: 100..1000)
User Load (2.9ms)  SELECT `users`.* FROM `users`  WHERE (`users`.`id` BETWEEN 1 AND 10000) AND (`users`.`id` BETWEEN 100 AND 1000)

为什么活动记录访问数据库两次?它已经有更大数据的结果。为什么它必须命中 db,而不仅仅是重用和切片 ActiveRecord::Relation?

有什么好的解决办法吗?

ActiveRecord 跟踪查询并能够缓存某些重复的请求,但在这种情况下,库无法立即了解第二个是第一个的子集。

此外,有几个原因导致像 ActiveRecord 这样的通用库可能不想实现这样的缓存逻辑。在非常大的应用程序中缓存大量数据集可能会导致内存占用数 Mb,并且进程可能会很快达到机器的内存限制,因为垃圾收集器将无法重新收集内存。

长话短说,在通用 ORM 库中实现此类功能是一个非常糟糕的主意。

如果您想在自己的代码中实现它,您可以自由实现。

ActiveRecord 正在访问数据库两次,因为您在控制台中 运行ning 它。这将通过 .inspect 在每一行上调用查询。如果这是代码块中的 运行,调用将延迟到您实际访问 user

而不是让两次迭代一次传递:

User.where("id between ? and ?", 100,1000)

它将减少数据库命中率,希望它能回答您的问题