a tool for shared writing and social publishing

make profile doc function faster

+66
+66
supabase/migrations/20260305100000_fix_profile_posts_performance.sql
··· 1 + -- Add missing indexes on document foreign keys used by get_profile_posts 2 + CREATE INDEX IF NOT EXISTS comments_on_documents_document_idx 3 + ON public.comments_on_documents (document); 4 + 5 + CREATE INDEX IF NOT EXISTS document_mentions_in_bsky_document_idx 6 + ON public.document_mentions_in_bsky (document); 7 + 8 + CREATE INDEX IF NOT EXISTS documents_in_publications_document_idx 9 + ON public.documents_in_publications (document); 10 + 11 + -- Add a stored generated column to extract the DID from at:// URIs 12 + -- at://did:plc:xxx/collection/rkey -> did:plc:xxx 13 + ALTER TABLE public.documents 14 + ADD COLUMN identity_did text GENERATED ALWAYS AS (split_part(uri, '/', 3)) STORED; 15 + 16 + -- Composite index for efficient profile post lookups: filter by DID, order by sort_date 17 + CREATE INDEX documents_identity_did_sort_idx 18 + ON public.documents (identity_did, sort_date DESC, uri DESC); 19 + 20 + -- Rewrite get_profile_posts to use the new identity_did column 21 + CREATE OR REPLACE FUNCTION get_profile_posts( 22 + p_did text, 23 + p_cursor_sort_date timestamptz DEFAULT NULL, 24 + p_cursor_uri text DEFAULT NULL, 25 + p_limit int DEFAULT 20 26 + ) 27 + RETURNS TABLE ( 28 + uri text, 29 + data jsonb, 30 + sort_date timestamptz, 31 + comments_count bigint, 32 + mentions_count bigint, 33 + recommends_count bigint, 34 + publication_uri text, 35 + publication_record jsonb, 36 + publication_name text 37 + ) 38 + LANGUAGE sql STABLE 39 + AS $$ 40 + SELECT 41 + d.uri, 42 + d.data, 43 + d.sort_date, 44 + (SELECT count(*) FROM comments_on_documents c WHERE c.document = d.uri), 45 + (SELECT count(*) FROM document_mentions_in_bsky m WHERE m.document = d.uri), 46 + (SELECT count(*) FROM recommends_on_documents r WHERE r.document = d.uri), 47 + pub.uri, 48 + pub.record, 49 + pub.name 50 + FROM documents d 51 + LEFT JOIN LATERAL ( 52 + SELECT p.uri, p.record, p.name 53 + FROM documents_in_publications dip 54 + JOIN publications p ON p.uri = dip.publication 55 + WHERE dip.document = d.uri 56 + LIMIT 1 57 + ) pub ON true 58 + WHERE d.identity_did = p_did 59 + AND ( 60 + p_cursor_sort_date IS NULL 61 + OR d.sort_date < p_cursor_sort_date 62 + OR (d.sort_date = p_cursor_sort_date AND d.uri < p_cursor_uri) 63 + ) 64 + ORDER BY d.sort_date DESC, d.uri DESC 65 + LIMIT p_limit; 66 + $$;