···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);
45-CREATE INDEX IF NOT EXISTS document_mentions_in_bsky_document_idx
6 ON public.document_mentions_in_bsky (document);
78-CREATE INDEX IF NOT EXISTS documents_in_publications_document_idx
9 ON public.documents_in_publications (document);
1011--- 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);
1920--- Rewrite get_profile_posts to use the new identity_did column
21CREATE OR REPLACE FUNCTION get_profile_posts(
22 p_did text,
23 p_cursor_sort_date timestamptz DEFAULT NULL,
···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
···1-- Add missing indexes on document foreign keys used by get_profile_posts
2+CREATE INDEX CONCURRENTLY IF NOT EXISTS comments_on_documents_document_idx
3 ON public.comments_on_documents (document);
45+CREATE INDEX CONCURRENTLY IF NOT EXISTS document_mentions_in_bsky_document_idx
6 ON public.document_mentions_in_bsky (document);
78+CREATE INDEX CONCURRENTLY IF NOT EXISTS documents_in_publications_document_idx
9 ON public.documents_in_publications (document);
1011+-- Expression index to look up documents by DID without adding a column
12+-- at://did:plc:xxx/collection/rkey -> split_part gives did:plc:xxx
13+CREATE INDEX CONCURRENTLY IF NOT EXISTS documents_identity_did_sort_idx
14+ ON public.documents (split_part(uri, '/', 3), sort_date DESC, uri DESC);
00001516+-- Rewrite get_profile_posts to use the expression index
17CREATE OR REPLACE FUNCTION get_profile_posts(
18 p_did text,
19 p_cursor_sort_date timestamptz DEFAULT NULL,
···51 WHERE dip.document = d.uri
52 LIMIT 1
53 ) pub ON true
54+ WHERE split_part(d.uri, '/', 3) = p_did
55 AND (
56 p_cursor_sort_date IS NULL
57 OR d.sort_date < p_cursor_sort_date