mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-07-30 23:55:59 +00:00
Fix (beta): compute num_notes via a subquery instead of Count()+distinct() (#13182)
DocumentViewSet.get_queryset() annotated num_notes via a LEFT JOIN to documents_note plus Count(), which requires the database to aggregate every matching document's note count before it can even sort or paginate the result -- on every list request, not just filtered ones. Switched to the same correlated-subquery pattern already used two lines above for effective_content (Subquery + OuterRef), which Django compiles to portable SQL across sqlite/postgresql/mariadb rather than a join-based aggregate. Benchmarked against a 100k synthetic document corpus (Postgres): the plain document list request dropped from ~2.2-2.4s to ~0.9-1.0s. Note that a separate, larger cost remains in the same queryset's plain .distinct() call, which still forces a full sort over every matching row regardless of this fix -- tracked separately, not addressed here. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
ff609c2987
commit
d8d8872414
+12
-1
@@ -1040,12 +1040,23 @@ class DocumentViewSet(
|
||||
.order_by("-id")
|
||||
.values("content")[:1],
|
||||
)
|
||||
# A correlated subquery avoids the LEFT JOIN + Count() this used to
|
||||
# be, which forced a GROUP BY aggregate over every matching document
|
||||
# before the query could even be sorted or limited.
|
||||
note_count = Subquery(
|
||||
Note.objects.filter(document=OuterRef("pk"))
|
||||
.order_by()
|
||||
.values("document")
|
||||
.annotate(count=Count("pk"))
|
||||
.values("count"),
|
||||
output_field=IntegerField(),
|
||||
)
|
||||
return (
|
||||
Document.objects.filter(root_document__isnull=True)
|
||||
.distinct()
|
||||
.order_by("-created", "-id")
|
||||
.annotate(effective_content=Coalesce(latest_version_content, F("content")))
|
||||
.annotate(num_notes=Count("notes"))
|
||||
.annotate(num_notes=Coalesce(note_count, 0))
|
||||
.select_related("correspondent", "storage_path", "document_type", "owner")
|
||||
.prefetch_related(
|
||||
Prefetch(
|
||||
|
||||
Reference in New Issue
Block a user