-- MCP Outline PostgreSQL - Recommended Indexes -- These indexes improve query performance for common MCP operations -- @author Descomplicar® | @link descomplicar.pt | @copyright 2026 -- -- IMPORTANT: Review these indexes before applying to production. -- Some may already exist in your Outline installation. -- Run with: psql -d outline -f migrations/001_indexes.sql -- ============================================================================ -- DOCUMENTS - Core document queries -- ============================================================================ -- Full-text search index (GIN for performance) -- Improves: outline_search_documents, outline_advanced_search CREATE INDEX IF NOT EXISTS idx_documents_search ON documents USING gin(to_tsvector('english', title || ' ' || COALESCE(text, ''))); -- Collection listing (most common query) -- Improves: outline_list_documents, outline_list_collection_documents CREATE INDEX IF NOT EXISTS idx_documents_collection_id ON documents("collectionId") WHERE "deletedAt" IS NULL; -- Published documents (for public views) -- Improves: queries filtering by publication status CREATE INDEX IF NOT EXISTS idx_documents_published ON documents("publishedAt" DESC) WHERE "deletedAt" IS NULL AND "publishedAt" IS NOT NULL; -- Recent documents (created at) -- Improves: outline_list_recent, analytics queries CREATE INDEX IF NOT EXISTS idx_documents_created ON documents("createdAt" DESC) WHERE "deletedAt" IS NULL; -- Updated documents -- Improves: outline_list_viewed_documents, activity tracking CREATE INDEX IF NOT EXISTS idx_documents_updated ON documents("updatedAt" DESC) WHERE "deletedAt" IS NULL; -- Archived documents -- Improves: outline_list_drafts with archive filter CREATE INDEX IF NOT EXISTS idx_documents_archived ON documents("archivedAt" DESC) WHERE "archivedAt" IS NOT NULL AND "deletedAt" IS NULL; -- Parent document hierarchy -- Improves: document tree traversal, outline_move_document CREATE INDEX IF NOT EXISTS idx_documents_parent ON documents("parentDocumentId") WHERE "deletedAt" IS NULL; -- Template documents -- Improves: outline_list_templates CREATE INDEX IF NOT EXISTS idx_documents_template ON documents("collectionId", "createdAt" DESC) WHERE template = true AND "deletedAt" IS NULL; -- Author lookup -- Improves: outline_get_user_activity, user document listings CREATE INDEX IF NOT EXISTS idx_documents_created_by ON documents("createdById", "createdAt" DESC) WHERE "deletedAt" IS NULL; -- ============================================================================ -- COLLECTIONS - Collection management -- ============================================================================ -- Active collections -- Improves: outline_list_collections CREATE INDEX IF NOT EXISTS idx_collections_active ON collections("createdAt" DESC) WHERE "deletedAt" IS NULL; -- Team collections -- Improves: team-scoped collection queries CREATE INDEX IF NOT EXISTS idx_collections_team ON collections("teamId") WHERE "deletedAt" IS NULL; -- ============================================================================ -- MEMBERSHIPS - Permission lookups (CRITICAL for performance) -- ============================================================================ -- Collection user memberships -- Improves: outline_list_collection_memberships, permission checks CREATE INDEX IF NOT EXISTS idx_collection_users_lookup ON collection_users("collectionId", "userId"); -- User's collections -- Improves: user permission verification CREATE INDEX IF NOT EXISTS idx_collection_users_user ON collection_users("userId"); -- Collection group memberships -- Improves: outline_list_collection_group_memberships CREATE INDEX IF NOT EXISTS idx_collection_groups_lookup ON collection_group_memberships("collectionId", "groupId"); -- Group user memberships -- Improves: outline_list_group_members CREATE INDEX IF NOT EXISTS idx_group_users_lookup ON group_users("groupId", "userId"); -- Document memberships -- Improves: outline_list_document_memberships CREATE INDEX IF NOT EXISTS idx_document_users_lookup ON user_permissions("documentId", "userId"); -- ============================================================================ -- USERS - User management -- ============================================================================ -- Active users by role -- Improves: outline_list_users with filter CREATE INDEX IF NOT EXISTS idx_users_active_role ON users(role, "createdAt" DESC) WHERE "deletedAt" IS NULL AND "suspendedAt" IS NULL; -- Email lookup (for authentication) -- Improves: user search by email CREATE INDEX IF NOT EXISTS idx_users_email ON users(email) WHERE "deletedAt" IS NULL; -- Team users -- Improves: team-scoped user queries CREATE INDEX IF NOT EXISTS idx_users_team ON users("teamId") WHERE "deletedAt" IS NULL; -- ============================================================================ -- GROUPS - Group management -- ============================================================================ -- Active groups -- Improves: outline_list_groups CREATE INDEX IF NOT EXISTS idx_groups_active ON groups("createdAt" DESC) WHERE "deletedAt" IS NULL; -- ============================================================================ -- STARS, PINS, VIEWS - User interaction tracking -- ============================================================================ -- User stars (bookmarks) -- Improves: outline_stars_list CREATE INDEX IF NOT EXISTS idx_stars_user ON stars("userId", "createdAt" DESC); -- Document stars -- Improves: document bookmark count CREATE INDEX IF NOT EXISTS idx_stars_document ON stars("documentId") WHERE "deletedAt" IS NULL; -- Pins by collection -- Improves: outline_pins_list CREATE INDEX IF NOT EXISTS idx_pins_collection ON pins("collectionId", index); -- Document views -- Improves: outline_views_list, view analytics CREATE INDEX IF NOT EXISTS idx_views_document ON views("documentId", "createdAt" DESC); -- User views -- Improves: outline_list_viewed_documents CREATE INDEX IF NOT EXISTS idx_views_user ON views("userId", "createdAt" DESC); -- ============================================================================ -- COMMENTS - Comment system -- ============================================================================ -- Document comments -- Improves: outline_comments_list CREATE INDEX IF NOT EXISTS idx_comments_document ON comments("documentId", "createdAt" DESC) WHERE "deletedAt" IS NULL; -- Unresolved comments -- Improves: comment resolution tracking CREATE INDEX IF NOT EXISTS idx_comments_unresolved ON comments("documentId", "createdAt" DESC) WHERE "deletedAt" IS NULL AND "resolvedAt" IS NULL; -- ============================================================================ -- SHARES - Document sharing -- ============================================================================ -- Document shares -- Improves: outline_shares_list CREATE INDEX IF NOT EXISTS idx_shares_document ON shares("documentId") WHERE "revokedAt" IS NULL; -- Share URL lookup -- Improves: public share access CREATE INDEX IF NOT EXISTS idx_shares_url ON shares("urlId") WHERE "revokedAt" IS NULL; -- ============================================================================ -- REVISIONS - Version history -- ============================================================================ -- Document revisions -- Improves: outline_revisions_list CREATE INDEX IF NOT EXISTS idx_revisions_document ON revisions("documentId", "createdAt" DESC); -- ============================================================================ -- EVENTS - Audit log (CRITICAL for analytics) -- ============================================================================ -- Actor events (who did what) -- Improves: outline_events_list with actor filter, user activity CREATE INDEX IF NOT EXISTS idx_events_actor ON events("actorId", "createdAt" DESC); -- Model events (what happened to what) -- Improves: outline_events_list with document/collection filter CREATE INDEX IF NOT EXISTS idx_events_model ON events("modelId", "createdAt" DESC); -- Event name (type of event) -- Improves: outline_events_list with name filter, analytics CREATE INDEX IF NOT EXISTS idx_events_name ON events(name, "createdAt" DESC); -- Team events -- Improves: team-scoped audit queries CREATE INDEX IF NOT EXISTS idx_events_team ON events("teamId", "createdAt" DESC); -- Date range queries -- Improves: analytics date filtering CREATE INDEX IF NOT EXISTS idx_events_created ON events("createdAt" DESC); -- ============================================================================ -- ATTACHMENTS - File management -- ============================================================================ -- Document attachments -- Improves: outline_attachments_list CREATE INDEX IF NOT EXISTS idx_attachments_document ON attachments("documentId") WHERE "deletedAt" IS NULL; -- ============================================================================ -- FILE OPERATIONS - Import/Export jobs -- ============================================================================ -- User file operations -- Improves: outline_file_operations_list CREATE INDEX IF NOT EXISTS idx_file_operations_user ON file_operations("userId", "createdAt" DESC); -- ============================================================================ -- SEARCH QUERIES - Search analytics -- ============================================================================ -- Search query analytics -- Improves: outline_search_queries_list, search analytics CREATE INDEX IF NOT EXISTS idx_search_queries_created ON search_queries("createdAt" DESC); -- Popular searches -- Improves: search suggestions CREATE INDEX IF NOT EXISTS idx_search_queries_query ON search_queries(query, "createdAt" DESC); -- ============================================================================ -- BACKLINKS - Document references -- ============================================================================ -- Document backlinks -- Improves: outline_backlinks_list CREATE INDEX IF NOT EXISTS idx_backlinks_document ON backlinks("documentId"); -- Reverse backlinks (what links to this) -- Improves: linked document lookup CREATE INDEX IF NOT EXISTS idx_backlinks_reverse ON backlinks("reverseDocumentId"); -- ============================================================================ -- NOTIFICATIONS - User notifications -- ============================================================================ -- User notifications -- Improves: outline_notifications_list CREATE INDEX IF NOT EXISTS idx_notifications_user ON notifications("userId", "createdAt" DESC); -- Unread notifications -- Improves: notification count CREATE INDEX IF NOT EXISTS idx_notifications_unread ON notifications("userId", "createdAt" DESC) WHERE "readAt" IS NULL; -- ============================================================================ -- SUBSCRIPTIONS - Document subscriptions -- ============================================================================ -- User subscriptions -- Improves: outline_subscriptions_list CREATE INDEX IF NOT EXISTS idx_subscriptions_user ON subscriptions("userId", "createdAt" DESC); -- Document subscriptions -- Improves: subscriber notifications CREATE INDEX IF NOT EXISTS idx_subscriptions_document ON subscriptions("documentId"); -- ============================================================================ -- COMPOSITE INDEXES for complex queries -- ============================================================================ -- Collection documents with sorting -- Improves: outline_list_collection_documents with sort CREATE INDEX IF NOT EXISTS idx_documents_collection_title ON documents("collectionId", title) WHERE "deletedAt" IS NULL; -- User activity by date -- Improves: outline_get_user_activity CREATE INDEX IF NOT EXISTS idx_events_actor_date ON events("actorId", name, "createdAt" DESC); -- ============================================================================ -- VERIFY INDEXES -- ============================================================================ -- List all indexes created by this migration -- SELECT indexname, tablename FROM pg_indexes -- WHERE indexname LIKE 'idx_%' ORDER BY tablename, indexname;