sql - rails : Reducing the amount of ActiveStorage queries

标签 sql ruby-on-rails performance rails-activestorage

我有一个索引页,显示 3 个不同的资源(Ablum、Samplepack 和 Demo),其中 2 个已附加图像。我通过我的 Controller 加载它们,如下所示:

# static_controller.rb   
  @resources = []
  @resources.push(Album.all, Demo.all, Samplepack.all)

它会产生大量 SQL 查询来加载它们。我想知道是否有最有效的方法来加载附件?如果有人可以复制/粘贴一些读物的链接给我,那就太棒了! 我正在考虑 includes 的事情或joins但我在网上找不到任何引用。

祝你有美好的一天

编辑:正如塞巴斯蒂安·帕尔马提到的,with_attached_<attachment>是必需的(为了简洁起见,没有详尽的日志)

 [Album.all, Demo.all, Samplepack.all]

# resulting SQL

  # Album n°1
  ActiveStorage::Attachment Load (1.8ms)   SELECT  "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4  [["record_id", 82], ["record_type", "Album"], ["name", "album_artwork"], ["LIMIT", 1]]
  ActiveStorage::Blob Load (2.4ms)         SELECT  "active_storage_blobs".*       FROM "active_storage_blobs"       WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 1227], ["LIMIT", 1]]
  # Ablum n°2 
  ActiveStorage::Attachment Load (0.2ms)   SELECT  "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4  [["record_id", 83], ["record_type", "Album"], ["name", "album_artwork"], ["LIMIT", 1]]
  ActiveStorage::Blob Load (0.1ms)         SELECT  "active_storage_blobs".*       FROM "active_storage_blobs"       WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 1228], ["LIMIT", 1]]
  # Album n°3
  ActiveStorage::Attachment Load (0.2ms)   SELECT  "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4  [["record_id", 84], ["record_type", "Album"], ["name", "album_artwork"], ["LIMIT", 1]]
  ActiveStorage::Blob Load (0.2ms)         SELECT  "active_storage_blobs".*       FROM "active_storage_blobs"       WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 1229], ["LIMIT", 1]]
  ...
  ... N+1 town (even N+2 ?)

使用with_attached_<attachment> :

 @resources = [
   Album.with_attached_album_artwork.all,
   Demo.all,
   Samplepack.with_attached_album_artwork.all
 ]

  # Albums
  ActiveStorage::Attachment Load (0.6ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_type" = $1 AND "active_storage_attachments"."name" = $2 AND "active_storage_attachments"."record_id" IN ($3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)  [["record_type", "Album"], ["name", "album_artwork"], ["record_id", 82], ["record_id", 83], ["record_id", 84], ["record_id", 85], ["record_id", 86], ["record_id", 87], ["record_id", 88], ["record_id", 89], ["record_id", 91], ["record_id", 93], ["record_id", 94], ["record_id", 95]]
  ActiveStorage::Blob Load (0.4ms)        SELECT "active_storage_blobs".*       FROM "active_storage_blobs"       WHERE "active_storage_blobs"."id" IN ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)  [["id", 1239], ["id", 1242], ["id", 1244], ["id", 1227], ["id", 1228], ["id", 1229], ["id", 1230], ["id", 1231], ["id", 1232], ["id", 1236], ["id", 1237], ["id", 1241]]

  # Samplepacks
  ActiveStorage::Attachment Load (0.3ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_type" = $1 AND "active_storage_attachments"."name" = $2 AND "active_storage_attachments"."record_id" = $3  [["record_type", "Samplepack"], ["name", "album_artwork"], ["record_id", 56]]
  ActiveStorage::Blob Load (0.2ms)        SELECT "active_storage_blobs".*       FROM "active_storage_blobs"       WHERE "active_storage_blobs"."id" = $1  [["id", 1243]]

最佳答案

根据您的情况( has_many/has_one )使用 with_attached_<attachment> :

To avoid N+1 queries, you can include the attached blobs in your query like so:

Gallery.where(user: Current.user).with_attached_photos

所以:

[
  Album.all,
  Demo.with_attached_images.all,
  Samplepack.with_attached_images.all
]

我认为没有必要创建一个空数组来填充它。

由于您使用的是all,所以可能还有一个问题,检查每个型号您真正需要什么。

关于sql - rails : Reducing the amount of ActiveStorage queries,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57357892/

相关文章:

php - 如何在同一个SQL中从两个不同的表中获取两个值

sql - 从表中返回随机的、不重复的行 - PostgreSQL

ruby-on-rails - Rails 中的 NoMethodError::MailersController#preview

asp.net-mvc - ASP.Net MVC Razor Views - 在构建时缩小 HTML

python - 简化python中的循环

sql - 无法解决联合选择中的排序规则冲突

sql - 新手请教一个关于数据库事务的问题

javascript - 在 Ruby on Rails 项目中使用 Particle.js

ruby-on-rails - 如何测试 Rails 中的嵌套路由

android - ListView 与线性布局