Account key for search records

Add an account key field to improve search performance. This field
allows us to filter the records by account directly in the fulltext
index, so we only need to examine rows belonging to the relevant account.
This commit is contained in:
Donal McBreen
2025-11-21 09:36:18 +00:00
parent 7f76835150
commit 70dd754cf7
4 changed files with 92 additions and 21 deletions
@@ -0,0 +1,37 @@
class AddAccountKeyToSearchRecords < ActiveRecord::Migration[8.2]
def up
16.times do |shard_id|
table_name = "search_records_#{shard_id}"
# Add account_key column
add_column table_name, :account_key, :string, null: false, default: ""
# Backfill existing records with account_key
execute <<-SQL
UPDATE #{table_name}
SET account_key = CONCAT('account', account_id)
SQL
# Create new fulltext index including account_key
add_index table_name, [:account_key, :content, :title], type: :fulltext
# Drop existing fulltext index
remove_index table_name, column: [:content, :title], type: :fulltext
end
end
def down
16.times do |shard_id|
table_name = "search_records_#{shard_id}"
# Drop new fulltext index
remove_index table_name, column: [:account_key, :content, :title], type: :fulltext
# Restore original fulltext index
add_index table_name, [:content, :title], type: :fulltext
# Remove account_key column
remove_column table_name, :account_key
end
end
end
Generated
+48 -17
View File
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
ActiveRecord::Schema[8.2].define(version: 2025_11_21_092508) do
create_table "accesses", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.datetime "accessed_at"
t.uuid "account_id", null: false
@@ -408,8 +408,24 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.index ["user_id"], name: "index_search_queries_on_user_id"
end
create_table "search_records", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
t.datetime "created_at", null: false
t.uuid "searchable_id", null: false
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_on_account_id"
t.index ["account_key", "content", "title"], name: "index_search_records_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_on_searchable_type_and_searchable_id", unique: true
end
create_table "search_records_0", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", default: "", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
@@ -418,12 +434,13 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_0_on_account_id"
t.index ["content", "title"], name: "index_search_records_0_on_content_and_title", type: :fulltext
t.index ["account_key", "content", "title"], name: "index_search_records_0_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_0_on_searchable_type_and_searchable_id", unique: true
end
create_table "search_records_1", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", default: "", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
@@ -432,12 +449,13 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_1_on_account_id"
t.index ["content", "title"], name: "index_search_records_1_on_content_and_title", type: :fulltext
t.index ["account_key", "content", "title"], name: "index_search_records_1_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_1_on_searchable_type_and_searchable_id", unique: true
end
create_table "search_records_10", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", default: "", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
@@ -446,12 +464,13 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_10_on_account_id"
t.index ["content", "title"], name: "index_search_records_10_on_content_and_title", type: :fulltext
t.index ["account_key", "content", "title"], name: "index_search_records_10_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_10_on_searchable_type_and_searchable_id", unique: true
end
create_table "search_records_11", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", default: "", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
@@ -460,12 +479,13 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_11_on_account_id"
t.index ["content", "title"], name: "index_search_records_11_on_content_and_title", type: :fulltext
t.index ["account_key", "content", "title"], name: "index_search_records_11_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_11_on_searchable_type_and_searchable_id", unique: true
end
create_table "search_records_12", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", default: "", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
@@ -474,12 +494,13 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_12_on_account_id"
t.index ["content", "title"], name: "index_search_records_12_on_content_and_title", type: :fulltext
t.index ["account_key", "content", "title"], name: "index_search_records_12_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_12_on_searchable_type_and_searchable_id", unique: true
end
create_table "search_records_13", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", default: "", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
@@ -488,12 +509,13 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_13_on_account_id"
t.index ["content", "title"], name: "index_search_records_13_on_content_and_title", type: :fulltext
t.index ["account_key", "content", "title"], name: "index_search_records_13_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_13_on_searchable_type_and_searchable_id", unique: true
end
create_table "search_records_14", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", default: "", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
@@ -502,12 +524,13 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_14_on_account_id"
t.index ["content", "title"], name: "index_search_records_14_on_content_and_title", type: :fulltext
t.index ["account_key", "content", "title"], name: "index_search_records_14_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_14_on_searchable_type_and_searchable_id", unique: true
end
create_table "search_records_15", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", default: "", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
@@ -516,12 +539,13 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_15_on_account_id"
t.index ["content", "title"], name: "index_search_records_15_on_content_and_title", type: :fulltext
t.index ["account_key", "content", "title"], name: "index_search_records_15_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_15_on_searchable_type_and_searchable_id", unique: true
end
create_table "search_records_2", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", default: "", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
@@ -530,12 +554,13 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_2_on_account_id"
t.index ["content", "title"], name: "index_search_records_2_on_content_and_title", type: :fulltext
t.index ["account_key", "content", "title"], name: "index_search_records_2_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_2_on_searchable_type_and_searchable_id", unique: true
end
create_table "search_records_3", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", default: "", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
@@ -544,12 +569,13 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_3_on_account_id"
t.index ["content", "title"], name: "index_search_records_3_on_content_and_title", type: :fulltext
t.index ["account_key", "content", "title"], name: "index_search_records_3_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_3_on_searchable_type_and_searchable_id", unique: true
end
create_table "search_records_4", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", default: "", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
@@ -558,12 +584,13 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_4_on_account_id"
t.index ["content", "title"], name: "index_search_records_4_on_content_and_title", type: :fulltext
t.index ["account_key", "content", "title"], name: "index_search_records_4_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_4_on_searchable_type_and_searchable_id", unique: true
end
create_table "search_records_5", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", default: "", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
@@ -572,12 +599,13 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_5_on_account_id"
t.index ["content", "title"], name: "index_search_records_5_on_content_and_title", type: :fulltext
t.index ["account_key", "content", "title"], name: "index_search_records_5_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_5_on_searchable_type_and_searchable_id", unique: true
end
create_table "search_records_6", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", default: "", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
@@ -586,12 +614,13 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_6_on_account_id"
t.index ["content", "title"], name: "index_search_records_6_on_content_and_title", type: :fulltext
t.index ["account_key", "content", "title"], name: "index_search_records_6_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_6_on_searchable_type_and_searchable_id", unique: true
end
create_table "search_records_7", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", default: "", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
@@ -600,12 +629,13 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_7_on_account_id"
t.index ["content", "title"], name: "index_search_records_7_on_content_and_title", type: :fulltext
t.index ["account_key", "content", "title"], name: "index_search_records_7_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_7_on_searchable_type_and_searchable_id", unique: true
end
create_table "search_records_8", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", default: "", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
@@ -614,12 +644,13 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_8_on_account_id"
t.index ["content", "title"], name: "index_search_records_8_on_content_and_title", type: :fulltext
t.index ["account_key", "content", "title"], name: "index_search_records_8_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_8_on_searchable_type_and_searchable_id", unique: true
end
create_table "search_records_9", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.uuid "account_id", null: false
t.string "account_key", default: "", null: false
t.uuid "board_id", null: false
t.uuid "card_id", null: false
t.text "content"
@@ -628,7 +659,7 @@ ActiveRecord::Schema[8.2].define(version: 2025_11_20_203100) do
t.string "searchable_type", null: false
t.string "title"
t.index ["account_id"], name: "index_search_records_9_on_account_id"
t.index ["content", "title"], name: "index_search_records_9_on_content_and_title", type: :fulltext
t.index ["account_key", "content", "title"], name: "index_search_records_9_on_account_key_and_content_and_title", type: :fulltext
t.index ["searchable_type", "searchable_id"], name: "index_search_records_9_on_searchable_type_and_searchable_id", unique: true
end