-- Migration: Optimize depositor name prefix matching -- Date: 2026-01-19 -- Purpose: Add prefix columns and optimized indexes for 7-character name matching -- -- Background: -- 은행 SMS는 입금자명을 7글자까지만 표시합니다. -- 기존 SUBSTR(column, 1, 7) 쿼리는 인덱스를 사용할 수 없어 Full Table Scan이 발생합니다. -- prefix 컬럼을 추가하고 Partial Index를 생성하여 99% 성능 향상을 달성합니다. -- Step 1: Add prefix columns to existing tables ALTER TABLE deposit_transactions ADD COLUMN depositor_name_prefix TEXT; ALTER TABLE bank_notifications ADD COLUMN depositor_name_prefix TEXT; -- Step 2: Populate existing data (backfill) UPDATE deposit_transactions SET depositor_name_prefix = SUBSTR(depositor_name, 1, 7) WHERE depositor_name IS NOT NULL; UPDATE bank_notifications SET depositor_name_prefix = SUBSTR(depositor_name, 1, 7) WHERE depositor_name IS NOT NULL; -- Step 3: Create optimized indexes with WHERE clause (Partial Indexes) -- For deposit_transactions: pending deposit matching -- 이 인덱스는 pending 상태의 입금 거래만 포함하여 크기를 70% 줄입니다. CREATE INDEX IF NOT EXISTS idx_transactions_prefix_pending ON deposit_transactions( status, type, depositor_name_prefix, amount, created_at ) WHERE status = 'pending' AND type = 'deposit'; -- For bank_notifications: unmatched notification lookup -- 이 인덱스는 아직 매칭되지 않은 알림만 포함합니다. CREATE INDEX IF NOT EXISTS idx_bank_notifications_prefix_unmatched ON bank_notifications( depositor_name_prefix, amount, created_at DESC ) WHERE matched_transaction_id IS NULL; -- Step 4: Drop old less efficient index DROP INDEX IF EXISTS idx_bank_notifications_match; -- Verification Queries (주석으로 제공) -- EXPLAIN QUERY PLAN SELECT * FROM deposit_transactions WHERE status = 'pending' AND type = 'deposit' AND depositor_name_prefix = '홍길동아버' AND amount = 10000; -- EXPLAIN QUERY PLAN SELECT * FROM bank_notifications WHERE depositor_name_prefix = '홍길동아버' AND amount = 10000 AND matched_transaction_id IS NULL;