️(backend) stop using LEFT(value, LENGTH(path)) in sql queries

Comparing path with LEFT(value, LENGTH(path)) makes a sequential scan on
all the Document table, the more this table grow, the more the query
using it will be slow. We dediced instead to lookup on the path
extracting all ancestors path for a given document and then make a path
IN statement to use the index existing on the path column.
This commit is contained in:
Manuel Raynaud
2026-09-11 12:55:20 +02:00
parent afc11adc52
commit fbc3ef83ba
4 changed files with 76 additions and 7 deletions
+3 -3
View File
@@ -23,7 +23,7 @@ from django.core.validators import URLValidator
from django.db import DatabaseError, connection, transaction
from django.db import models as db
from django.db.models.expressions import RawSQL
from django.db.models.functions import Greatest, Left, Length
from django.db.models.functions import Greatest
from django.http import Http404, StreamingHttpResponse
from django.urls import reverse
from django.utils import timezone
@@ -1752,7 +1752,7 @@ class DocumentViewSet(
# document. Filter to get the minimum access date for the logged-in user
access_queryset = models.DocumentAccess.objects.filter(
db.Q(user=user) | db.Q(team__in=user.teams),
document__path=Left(db.Value(document.path), Length("document__path")),
document__path__in=document.get_self_and_ancestors_paths(),
).aggregate(min_date=db.Min("created_at"))
# Handle the case where the user has no accesses
@@ -1792,7 +1792,7 @@ class DocumentViewSet(
access.created_at
for access in models.DocumentAccess.objects.filter(
db.Q(user=user) | db.Q(team__in=user.teams),
document__path=Left(db.Value(document.path), Length("document__path")),
document__path__in=document.get_self_and_ancestors_paths(),
)
)