From eea1ab3002760077fde6494a516e7482bf00aa6d Mon Sep 17 00:00:00 2001 From: Pranav Date: Fri, 27 Jun 2025 15:48:04 -0700 Subject: [PATCH] fix: Add composite index on messages for csat_metrics API performance (#11831) This PR adds a composite index (:account_id, :content_type, :created_at) on the table messages. This index is added as a temporary fix for performance issues in the CSAT responses controller where we query messages with account_id, content_type and created_at. The current implementation (account.message.input_csat.count) times out with millions of messages. TODO: Create a dedicated csat_survey table and add entries when surveys are sent, then query this table instead of the entire messages table for better performance. --- app/models/message.rb | 1 + .../20250627195529_add_index_to_messages.rb | 20 +++++++++++++++++++ db/schema.rb | 3 ++- 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20250627195529_add_index_to_messages.rb diff --git a/app/models/message.rb b/app/models/message.rb index e7c4e9b6c..d4036416e 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -24,6 +24,7 @@ # # Indexes # +# idx_messages_account_content_created (account_id,content_type,created_at) # index_messages_on_account_created_type (account_id,created_at,message_type) # index_messages_on_account_id (account_id) # index_messages_on_account_id_and_inbox_id (account_id,inbox_id) diff --git a/db/migrate/20250627195529_add_index_to_messages.rb b/db/migrate/20250627195529_add_index_to_messages.rb new file mode 100644 index 000000000..ff58c31d4 --- /dev/null +++ b/db/migrate/20250627195529_add_index_to_messages.rb @@ -0,0 +1,20 @@ +class AddIndexToMessages < ActiveRecord::Migration[7.0] + def change + # This index is added as a temporary fix for performance issues in the CSAT + # responses controller where we query messages with account_id, content_type + # and created_at. The current implementation (account.message.input_csat.count) + # times out with millions of messages. + # + # TODO: Create a dedicated csat_survey table and add entries when surveys are + # sent, then query this table instead of the entire messages table for better + # performance. + return if index_exists?( + :messages, + [:account_id, :content_type, :created_at], + name: 'idx_messages_account_content_created' + ) + + add_index :messages, [:account_id, :content_type, :created_at], + name: 'idx_messages_account_content_created', algorithm: :concurrently + end +end diff --git a/db/schema.rb b/db/schema.rb index fdd0cce82..af0c89086 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2025_06_20_120000) do +ActiveRecord::Schema[7.1].define(version: 2025_06_27_195529) do # These extensions should be enabled to support this database enable_extension "pg_stat_statements" enable_extension "pg_trgm" @@ -825,6 +825,7 @@ ActiveRecord::Schema[7.1].define(version: 2025_06_20_120000) do t.text "processed_message_content" t.jsonb "sentiment", default: {} t.index "((additional_attributes -> 'campaign_id'::text))", name: "index_messages_on_additional_attributes_campaign_id", using: :gin + t.index ["account_id", "content_type", "created_at"], name: "idx_messages_account_content_created" t.index ["account_id", "created_at", "message_type"], name: "index_messages_on_account_created_type" t.index ["account_id", "inbox_id"], name: "index_messages_on_account_id_and_inbox_id" t.index ["account_id"], name: "index_messages_on_account_id"