Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt

Use this file to discover all available pages before exploring further.

Version: 1.0.0
Date: 2026-01-17
Status: ✅ Complete

Executive Summary

This document tracks the index optimization work completed for Encore Health OS Platform as part of Phase 2A performance improvements.

Key Metrics

MetricBeforeAfter
Missing FK Indexes600 ✅
Tables with High Seq Scans35+Indexed
Duplicate Indexes30 ✅

Phase 2A: Foreign Key Indexes

Methodology

  1. Analysis: Queried pg_stat_user_tables for tables with high sequential scan counts
  2. Verification: Cross-referenced with actual schema to identify missing FK indexes
  3. Prioritization: Ordered by sequential scan count (highest first)
  4. Implementation: Created indexes in 3 batches by priority

Migration 1: High Priority (18 indexes)

Tables with >500 sequential scans:
TableColumnSeq Scans
pf_audit_logsuser_id1,503
pf_audit_logsrecord_id1,503
pf_notificationsuser_id1,356
pf_notificationstemplate_id1,356
pf_notificationsbatch_id1,356
fw_form_submissionsform_id1,161
hr_credential_renewal_workflowsemployee_id1,047
pf_taskssource_id693
lo_issuesmeeting_id684
lo_meetingsagenda_template_id677
hr_job_postingsposition_id522
hr_job_postingsdepartment_id522
hr_job_postingshiring_manager_id522
hr_offersapplication_id517
hr_offersposition_id517
hr_employee_credentialsemployee_id507
hr_employee_credentialscredential_type_id507
hr_interviewsapplication_id499

Migration 2: Medium Priority (15 indexes)

Tables with 200-500 sequential scans:
TableColumn
pf_ai_conversationsuser_id
pf_org_dashboard_defaultstemplate_id
hr_applicationsjob_posting_id
hr_employeesmanager_id
hr_employeesposition_id
hr_employeesdepartment_id
hr_employeesprimary_site_id
pf_wizard_templatescurrent_version_id
pf_wizard_templatessource_template_id
rh_episodesbed_id
rh_episodesresidence_id
rh_episodesresident_profile_id
hr_leave_requestsemployee_id
hr_incidentsemployee_id
hr_pay_ratesemployee_id

Migration 3: Standard Priority (27 indexes)

Finance and governance FK indexes:
TableColumn
fa_invoicescustomer_id
fa_invoicessite_id
fa_invoicesjournal_entry_id
fa_vendor_billsvendor_id
fa_vendor_billssite_id
fa_vendor_billsjournal_entry_id
fa_accountsparent_account_id
fa_accountsdefault_fund_id
fa_bank_accountsgl_account_id
fa_budgetsfiscal_year_id
fa_budgetsapproved_by
fa_budgetssubmitted_by
fa_customer_paymentscustomer_id
fa_customer_paymentsjournal_entry_id
fa_credit_memoscustomer_id
fa_credit_memosoriginal_invoice_id
fa_credit_memosjournal_entry_id
gr_contractsvendor_id
gr_contractsassigned_to
gr_policiescategory_id
gr_policiesapproved_by
fm_work_ordersasset_id
fm_work_ordersassigned_to
fm_work_orderssite_id
fm_inventory_itemscategory_id
fm_inventory_itemspreferred_vendor_id
pf_documentssite_id

Duplicate Index Cleanup

Removed 3 duplicate indexes that were redundant:
Index RemovedCovered By
Previously identified duplicatesCleaned in Phase 1

Index Verification

Check New Indexes

SELECT 
  indexname,
  tablename,
  indexdef
FROM pg_indexes
WHERE schemaname = 'public'
  AND indexname LIKE 'idx_%'
ORDER BY tablename, indexname;

Monitor Index Usage

-- Check index usage after 1 week
SELECT * FROM pf_get_unused_indexes();

Check for Missing Indexes

-- Find FKs without indexes
SELECT
  tc.table_name,
  kcu.column_name,
  ccu.table_name AS foreign_table_name
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
  ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage ccu
  ON ccu.constraint_name = tc.constraint_name
WHERE tc.constraint_type = 'FOREIGN KEY'
  AND NOT EXISTS (
    SELECT 1 FROM pg_indexes
    WHERE tablename = tc.table_name
      AND indexdef LIKE '%' || kcu.column_name || '%'
  )
ORDER BY tc.table_name;

Performance Impact

Expected Improvements

Query TypeBeforeAfter
FK lookupsSequential scanIndex scan
JOIN operationsSlow on large tablesOptimized
RLS policy checksSubquery per rowDirect lookup

Monitoring Queries

-- Check slow queries
SELECT * FROM pf_get_slow_queries(100, 20);

-- Check table bloat
SELECT * FROM pf_get_table_bloat();

Maintenance Recommendations

  1. Weekly: Run VACUUM ANALYZE on high-traffic tables (automatic via Supabase)
  2. Monthly: Check pf_get_unused_indexes() for indexes to remove
  3. Quarterly: Review pf_get_slow_queries() for new indexing opportunities

References