From 44b1047b905249f027ddc794c38ad440c92d1062 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Tue, 23 May 2023 17:22:47 +0530 Subject: [PATCH] feat(perf): contacts query performance (#7175) * feat: use more indexable where condition * feat: add index concurrently * chore: update schema * refactor: update index name --- app/models/contact.rb | 3 ++- ...30523104139_add_partial_index_for_resolved_contacts.rb | 8 ++++++++ db/schema.rb | 3 ++- 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20230523104139_add_partial_index_for_resolved_contacts.rb diff --git a/app/models/contact.rb b/app/models/contact.rb index 96457996f..b13e3d60e 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -19,6 +19,7 @@ # index_contacts_on_account_id (account_id) # index_contacts_on_lower_email_account_id (lower((email)::text), account_id) # index_contacts_on_name_email_phone_number_identifier (name,email,phone_number,identifier) USING gin +# index_contacts_on_identifiable_fields (account_id,email,phone_number,identifier) WHERE (((email)::text <> ''::text) OR ((phone_number)::text <> ''::text) OR ((identifier)::text <> ''::text)) # rubocop:disable Layout/LineLength # index_contacts_on_phone_number_and_account_id (phone_number,account_id) # uniq_email_per_account_contact (email,account_id) UNIQUE # uniq_identifier_per_account_contact (identifier,account_id) UNIQUE @@ -136,7 +137,7 @@ class Contact < ApplicationRecord end def self.resolved_contacts - where("COALESCE(NULLIF(contacts.email,''),NULLIF(contacts.phone_number,''),NULLIF(contacts.identifier,'')) IS NOT NULL") + where("contacts.email <> '' OR contacts.phone_number <> '' OR contacts.identifier <> ''") end def discard_invalid_attrs diff --git a/db/migrate/20230523104139_add_partial_index_for_resolved_contacts.rb b/db/migrate/20230523104139_add_partial_index_for_resolved_contacts.rb new file mode 100644 index 000000000..6302ea106 --- /dev/null +++ b/db/migrate/20230523104139_add_partial_index_for_resolved_contacts.rb @@ -0,0 +1,8 @@ +class AddPartialIndexForResolvedContacts < ActiveRecord::Migration[7.0] + disable_ddl_transaction! + + def change + add_index :contacts, [:account_id, :email, :phone_number, :identifier], where: "(email <> '' OR phone_number <> '' OR identifier <> '')", + name: 'index_contacts_on_nonempty_fields', algorithm: :concurrently + end +end diff --git a/db/schema.rb b/db/schema.rb index 171e8e12b..5875dd977 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.0].define(version: 2023_05_15_051424) do +ActiveRecord::Schema[7.0].define(version: 2023_05_23_104139) do # These are extensions that must be enabled in order to support this database enable_extension "pg_stat_statements" enable_extension "pg_trgm" @@ -405,6 +405,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_05_15_051424) do t.jsonb "custom_attributes", default: {} t.datetime "last_activity_at", precision: nil t.index "lower((email)::text), account_id", name: "index_contacts_on_lower_email_account_id" + t.index ["account_id", "email", "phone_number", "identifier"], name: "index_contacts_on_nonempty_fields", where: "(((email)::text <> ''::text) OR ((phone_number)::text <> ''::text) OR ((identifier)::text <> ''::text))" t.index ["account_id"], name: "index_contacts_on_account_id" t.index ["email", "account_id"], name: "uniq_email_per_account_contact", unique: true t.index ["identifier", "account_id"], name: "uniq_identifier_per_account_contact", unique: true