-- Phase 2: Vorlagen für EXPLAIN (ANALYZE, BUFFERS) auf Ziel-DB mit realistischem Datenbestand. -- Ersetzen: :token (Session), ggf. :club_id / :group_id nach Tenant; in psql: \set token '...' -- Hinweis: Routen sind auth-geschützt — sinnvoll mit Rolle ausführen, die der API entspricht, -- oder SQL aus Postgres-Logs normalisieren. -- GET /api/exercises — typische Liste (Filter anpassen) EXPLAIN (ANALYZE, BUFFERS) SELECT e.id, e.title FROM exercises e WHERE e.status <> 'archived' AND e.visibility IN ('private', 'club', 'official') ORDER BY e.updated_at DESC, e.id DESC LIMIT 50; -- GET /api/exercises — mit Stufenfilter (nutzt idx_exercise_skills_exercise_level_rank) EXPLAIN (ANALYZE, BUFFERS) SELECT e.id, e.title FROM exercises e WHERE e.status <> 'archived' AND EXISTS ( SELECT 1 FROM exercise_skills es WHERE es.exercise_id = e.id AND ( CASE COALESCE( NULLIF(TRIM(LOWER(es.target_level::text)), ''), NULLIF(TRIM(LOWER(es.required_level::text)), '') ) WHEN 'basis' THEN 1 WHEN 'grundlagen' THEN 2 WHEN 'aufbau' THEN 3 WHEN 'fortgeschritten' THEN 4 WHEN 'optimierung' THEN 5 WHEN 'einsteiger' THEN 1 WHEN 'experte' THEN 5 WHEN '1' THEN 1 WHEN '2' THEN 2 WHEN '3' THEN 3 WHEN '4' THEN 4 WHEN '5' THEN 5 ELSE NULL END ) BETWEEN 2 AND 4 ) ORDER BY e.updated_at DESC, e.id DESC LIMIT 50; -- GET /api/training-units — Kalenderliste (ohne Blueprint) EXPLAIN (ANALYZE, BUFFERS) SELECT tu.id, tu.planned_date, tu.planned_time_start FROM training_units tu LEFT JOIN training_groups tg ON tu.group_id = tg.id WHERE tu.framework_slot_id IS NULL ORDER BY tu.planned_date ASC, (tu.planned_time_start IS NULL) ASC, tu.planned_time_start ASC NULLS LAST, tu.id ASC LIMIT 40;