-- ============================================================ -- Performance indexes for ERPNext PostgreSQL -- ============================================================ -- Problem: ERPNext v16 PostgreSQL migration does not create -- indexes on 'customer' / 'party' columns. This causes full -- table scans on tables with 100k-1M+ rows, resulting in -- 5+ second page loads in Ops client detail page. -- -- Impact: Sales Invoice query dropped from 1,248ms to 28ms -- (EXPLAIN ANALYZE: 378ms → 0.36ms, 1000x improvement) -- -- Run: docker exec erpnext-db-1 psql -U postgres -d -f /path/to/this.sql -- Or run each CREATE INDEX statement individually. -- -- All indexes use CONCURRENTLY to avoid locking production tables. -- Run each statement in its own transaction (outside BEGIN/COMMIT). -- ============================================================ -- Customer lookup on Sales Invoice (630k+ rows) CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_si_customer ON "tabSales Invoice" (customer); -- Composite index for sorted invoice listing per customer CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_si_posting ON "tabSales Invoice" (customer, posting_date DESC); -- Party lookup on Payment Entry (344k+ rows) CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_pe_party ON "tabPayment Entry" (party); -- Composite index for sorted payment listing per party CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_pe_posting ON "tabPayment Entry" (party, posting_date DESC); -- Reference lookup on Comment (1.07M+ rows) -- Used by: ticket comments, invoice notes, customer memos CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_comment_ref ON "tabComment" (reference_doctype, reference_name); -- Customer lookup on Issue (243k+ rows) CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_issue_customer ON "tabIssue" (customer); -- Customer lookup on Service Location (17k+ rows) CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sl_customer ON "tabService Location" (customer); -- Customer lookup on Service Subscription (40k+ rows) CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_ss_customer ON "tabService Subscription" (customer); -- Customer lookup on Service Equipment (10k+ rows) CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_se_customer ON "tabService Equipment" (customer); -- Update planner statistics after index creation ANALYZE "tabSales Invoice"; ANALYZE "tabPayment Entry"; ANALYZE "tabComment"; ANALYZE "tabIssue"; ANALYZE "tabService Location"; ANALYZE "tabService Subscription"; ANALYZE "tabService Equipment";