如何减少命中分贝倍数
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)
它将减少数据库命中率,希望它能回答您的问题
假设我有十万用户
简单示例,
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)
它将减少数据库命中率,希望它能回答您的问题