With an index on (screen_id, level, created_at DESC) the database finds the latest event per screen without scanning the table.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # ====================================================================== # Q: For each screen I want its latest event (e.g. the latest error). How do you # do it without N+1? # # With an index on (screen_id, level, created_at DESC) the database finds the # latest event per screen without scanning the table. For "the last 3 records" I # use Prefetch with a window function or, on PostgreSQL, a LATERAL join in raw # SQL. # ====================================================================== from django.db.models import OuterRef, Subquery, Exists last_error = (ScreenEvent.objects .filter(screen=OuterRef('pk'), level='error') .order_by('-created_at')) screens = Screen.objects.filter(workspace=ws).annotate( last_error_msg=Subquery(last_error.values('message')[:1]), last_error_at=Subquery(last_error.values('created_at')[:1]), has_errors=Exists(last_error), ) |