-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Optimize DB requests in task list, quality conflicts list and cloudstorages #8275
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9efedb2
4846625
ddfee14
c4fb2cd
dc192b4
9be5176
91f3057
fcc456b
d8f9223
c382cc4
2864da1
dd0375e
0bebade
e1c2ef5
000537b
4e23622
ea02c54
b0ed635
47ba880
0390f7b
c5cac64
7984c36
3b2a6e9
faaf196
8f1d6bb
f1460e3
8e2e221
4039e4f
3d5c28a
c9a1fc1
3b87dae
04b1958
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
< 8000 /form>There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
### Fixed | ||
|
||
- Improved performance of `GET /api/tasks`, `GET /api/quality/conflicts` | ||
and `GET /api/cloudstorages` requests | ||
(<https://github.com/cvat-ai/cvat/pull/8275>) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2275,6 +2275,33 @@ def _create_files(self, instance, files): | |
[files_model(data=instance, **f) for f in files[files_type]] | ||
) | ||
|
||
class TaskReadListSerializer(serializers.ListSerializer): | ||
def to_representation(self, data): | ||
if isinstance(data, list) and data: | ||
# Optimized prefetch only for the current page | ||
page: list[models.Task] = data | ||
|
||
# Annotate page objects | ||
# We do it explicitly here and not in the LIST queryset to avoid | ||
# doing the 9E81 same DB computations twice - one time for the page retrieval | ||
# and another one for the COUNT(*) request to get the total count | ||
page_task_ids = set(t.id for t in page) | ||
job_summary_fields = [m.value for m in models.TaskQuerySet.JobSummaryFields] | ||
job_counts = { | ||
task["id"]: task | ||
for task in models.Task.objects | ||
.filter(id__in=page_task_ids) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just thought of something WRT this and similar optimizations - how well does this behave when There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
.with_job_summary() | ||
.values("id", *job_summary_fields) | ||
} | ||
|
||
for task in page: | ||
task_job_summary = job_counts.get(task.id) | ||
for k in job_summary_fields: | ||
setattr(task, k, task_job_summary[k]) | ||
|
||
return super().to_representation(data) | ||
|
||
class TaskReadSerializer(serializers.ModelSerializer): | ||
data_chunk_size = serializers.ReadOnlyField(source='data.chunk_size', required=False) | ||
data_compressed_chunk_type = serializers.ReadOnlyField(source='data.compressed_chunk_type', required=False) | ||
|
@@ -2313,6 +2340,7 @@ class Meta: | |
'organization': { 'allow_null': True }, | ||
'overlap': { 'allow_null': True }, | ||
} | ||
list_serializer_class = TaskReadListSerializer | ||
|
||
def get_consensus_enabled(self, instance: models.Task) -> bool: | ||
return instance.consensus_replicas > 0 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, I think that's a bug, so I filed a Django bug report: https://code.djangoproject.com/ticket/36372.