Add cached fields to Item model for searching, but don't use them yet
This is the first part of a change to improve search performance, by caching occupied zone IDs and supported body IDs onto the Item record itself, instead of always doing joins with `SwfAsset`. It's unfortunate, because part of the power of SQL is joins! But doing joins with big tables, in ways that can't take advantage of indexes in the same ways as we often want to, is… slow. It's possible there's something I'm misunderstanding about SQL optimization, and this _could_ be done with query optimization or indexes instead of duplicating data like this? This complexity carries the risk of data getting out of sync in unforeseen ways. But this is what I know how to do, and it seems to be working, so! Okay!
This commit is contained in:
parent
4a431a4ae8
commit
efda6d74ab
4 changed files with 34 additions and 3 deletions
|
@ -296,6 +296,12 @@ class Item < ApplicationRecord
|
||||||
restricted_zones + occupied_zones
|
restricted_zones + occupied_zones
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_cached_fields
|
||||||
|
self.cached_occupied_zone_ids = occupied_zone_ids.sort.join(",")
|
||||||
|
self.cached_compatible_body_ids = compatible_body_ids.sort.join(",")
|
||||||
|
self.save!
|
||||||
|
end
|
||||||
|
|
||||||
def species_support_ids
|
def species_support_ids
|
||||||
@species_support_ids_array ||= read_attribute('species_support_ids').split(',').map(&:to_i) rescue nil
|
@species_support_ids_array ||= read_attribute('species_support_ids').split(',').map(&:to_i) rescue nil
|
||||||
end
|
end
|
||||||
|
@ -305,7 +311,7 @@ class Item < ApplicationRecord
|
||||||
replacement = replacement.join(',') if replacement.is_a?(Array)
|
replacement = replacement.join(',') if replacement.is_a?(Array)
|
||||||
write_attribute('species_support_ids', replacement)
|
write_attribute('species_support_ids', replacement)
|
||||||
end
|
end
|
||||||
|
|
||||||
def support_species?(species)
|
def support_species?(species)
|
||||||
species_support_ids.blank? || species_support_ids.include?(species.id)
|
species_support_ids.blank? || species_support_ids.include?(species.id)
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,9 @@ class ParentSwfAssetRelationship < ApplicationRecord
|
||||||
belongs_to :parent, :polymorphic => true
|
belongs_to :parent, :polymorphic => true
|
||||||
|
|
||||||
belongs_to :swf_asset
|
belongs_to :swf_asset
|
||||||
|
|
||||||
|
after_save :update_parent_cached_fields
|
||||||
|
after_destroy :update_parent_cached_fields
|
||||||
|
|
||||||
def item=(replacement)
|
def item=(replacement)
|
||||||
self.parent = replacement
|
self.parent = replacement
|
||||||
|
@ -16,4 +19,8 @@ class ParentSwfAssetRelationship < ApplicationRecord
|
||||||
def pet_state=(replacement)
|
def pet_state=(replacement)
|
||||||
self.parent = replacement
|
self.parent = replacement
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_parent_cached_fields
|
||||||
|
parent.try(:update_cached_fields)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
16
db/migrate/20241001052510_add_cached_fields_to_items.rb
Normal file
16
db/migrate/20241001052510_add_cached_fields_to_items.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
class AddCachedFieldsToItems < ActiveRecord::Migration[7.2]
|
||||||
|
def change
|
||||||
|
add_column :items, :cached_occupied_zone_ids, :string, null: false, default: ""
|
||||||
|
add_column :items, :cached_compatible_body_ids, :text, null: false, default: ""
|
||||||
|
|
||||||
|
reversible do |direction|
|
||||||
|
direction.up do
|
||||||
|
puts "Updating cached item fields for all items…"
|
||||||
|
Item.includes(:swf_assets).find_in_batches.with_index do |items, batch|
|
||||||
|
puts "Updating item batch ##{batch+1}…"
|
||||||
|
items.each(&:update_cached_fields)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[7.2].define(version: 2024_09_28_022359) do
|
ActiveRecord::Schema[7.2].define(version: 2024_10_01_052510) do
|
||||||
create_table "alt_styles", charset: "utf8mb4", collation: "utf8mb4_unicode_520_ci", force: :cascade do |t|
|
create_table "alt_styles", charset: "utf8mb4", collation: "utf8mb4_unicode_520_ci", force: :cascade do |t|
|
||||||
t.integer "species_id", null: false
|
t.integer "species_id", null: false
|
||||||
t.integer "color_id", null: false
|
t.integer "color_id", null: false
|
||||||
|
@ -137,6 +137,8 @@ ActiveRecord::Schema[7.2].define(version: 2024_09_28_022359) do
|
||||||
t.text "description", size: :medium, null: false
|
t.text "description", size: :medium, null: false
|
||||||
t.string "rarity", default: "", null: false
|
t.string "rarity", default: "", null: false
|
||||||
t.integer "dyeworks_base_item_id"
|
t.integer "dyeworks_base_item_id"
|
||||||
|
t.string "cached_occupied_zone_ids", default: "", null: false
|
||||||
|
t.text "cached_compatible_body_ids", default: "", null: false
|
||||||
t.index ["dyeworks_base_item_id"], name: "index_items_on_dyeworks_base_item_id"
|
t.index ["dyeworks_base_item_id"], name: "index_items_on_dyeworks_base_item_id"
|
||||||
t.index ["modeling_status_hint", "created_at", "id"], name: "items_modeling_status_hint_and_created_at_and_id"
|
t.index ["modeling_status_hint", "created_at", "id"], name: "items_modeling_status_hint_and_created_at_and_id"
|
||||||
t.index ["modeling_status_hint", "created_at"], name: "items_modeling_status_hint_and_created_at"
|
t.index ["modeling_status_hint", "created_at"], name: "items_modeling_status_hint_and_created_at"
|
||||||
|
@ -154,7 +156,7 @@ ActiveRecord::Schema[7.2].define(version: 2024_09_28_022359) do
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "modeling_logs", id: :integer, charset: "utf8mb4", collation: "utf8mb4_unicode_520_ci", force: :cascade do |t|
|
create_table "modeling_logs", id: :integer, charset: "utf8mb4", collation: "utf8mb4_unicode_520_ci", force: :cascade do |t|
|
||||||
t.datetime "created_at", precision: nil, default: -> { "CURRENT_TIMESTAMP" }, null: false
|
t.datetime "created_at", precision: nil, default: -> { "current_timestamp()" }, null: false
|
||||||
t.text "log_json", size: :long, null: false
|
t.text "log_json", size: :long, null: false
|
||||||
t.string "pet_name", limit: 128, null: false
|
t.string "pet_name", limit: 128, null: false
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue