Rails:减少 ActiveStorage 查询量
Rails: Reducing the amount of ActiveStorage queries
我有一个显示 3 种不同资源(Ablum、Samplepack 和 Demo)的索引页面,其中 2 种附有图像。我像这样通过我的控制器加载它们:
# static_controller.rb
@resources = []
@resources.push(Album.all, Demo.all, Samplepack.all)
它导致 很多 的 SQL 查询以便加载它们。我想知道是否有最有效的加载附件的方法?如果有人可以 copy/paste 我 link 读一些书,那就太棒了!
我在考虑 includes
或 joins
的东西,但我在网上找不到任何参考。
祝你有愉快的一天
编辑: 正如 Sebastian Palma 提到的,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" = AND "active_storage_attachments"."record_type" = AND "active_storage_attachments"."name" = LIMIT [["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" = LIMIT [["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" = AND "active_storage_attachments"."record_type" = AND "active_storage_attachments"."name" = LIMIT [["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" = LIMIT [["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" = AND "active_storage_attachments"."record_type" = AND "active_storage_attachments"."name" = LIMIT [["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" = LIMIT [["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" = AND "active_storage_attachments"."name" = AND "active_storage_attachments"."record_id" IN (, , , , , , , , , , , ) [["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 (, , , , , , , , , , , ) [["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" = AND "active_storage_attachments"."name" = AND "active_storage_attachments"."record_id" = [["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" = [["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
,请检查每个型号的真正需求。
我有一个显示 3 种不同资源(Ablum、Samplepack 和 Demo)的索引页面,其中 2 种附有图像。我像这样通过我的控制器加载它们:
# static_controller.rb
@resources = []
@resources.push(Album.all, Demo.all, Samplepack.all)
它导致 很多 的 SQL 查询以便加载它们。我想知道是否有最有效的加载附件的方法?如果有人可以 copy/paste 我 link 读一些书,那就太棒了!
我在考虑 includes
或 joins
的东西,但我在网上找不到任何参考。
祝你有愉快的一天
编辑: 正如 Sebastian Palma 提到的,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" = AND "active_storage_attachments"."record_type" = AND "active_storage_attachments"."name" = LIMIT [["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" = LIMIT [["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" = AND "active_storage_attachments"."record_type" = AND "active_storage_attachments"."name" = LIMIT [["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" = LIMIT [["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" = AND "active_storage_attachments"."record_type" = AND "active_storage_attachments"."name" = LIMIT [["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" = LIMIT [["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" = AND "active_storage_attachments"."name" = AND "active_storage_attachments"."record_id" IN (, , , , , , , , , , , ) [["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 (, , , , , , , , , , , ) [["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" = AND "active_storage_attachments"."name" = AND "active_storage_attachments"."record_id" = [["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" = [["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
,请检查每个型号的真正需求。