Skip to content

Commit

Permalink
Merge pull request #136 from biigle/patch-1
Browse files Browse the repository at this point in the history
Improve performance of "only newest label" query even more
  • Loading branch information
mzur authored Dec 11, 2024
2 parents 2ad6699 + 3ec2055 commit ce933bc
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public function initQuery($columns = [])
->when($this->isRestrictedToExportArea(), [$this, 'restrictToExportAreaQuery'])
->when($this->isRestrictedToAnnotationSession(), [$this, 'restrictToAnnotationSessionQuery'])
->when($this->isRestrictedToNewestLabel(), function ($query) {
return $this->restrictToNewestLabelQuery($query, 'image_annotation_labels');
return $this->restrictToNewestLabelQuery($query, $this->source);
})
->when($this->isRestrictedToLabels(), function ($query) {
return $this->restrictToLabelsQuery($query, 'image_annotation_labels');
Expand Down
2 changes: 1 addition & 1 deletion src/Support/Reports/Volumes/ImageIfdoReportGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ protected function query()
},
'annotations.labels' => function ($query) {
if ($this->isRestrictedToNewestLabel()) {
$query = $this->restrictToNewestLabelQuery($query, 'image_annotation_labels');
$query = $this->restrictToNewestLabelQuery($query, $this->source);
}

if ($this->isRestrictedToLabels()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public function initQuery($columns = [])
->where('videos.volume_id', $this->source->id)
->when($this->isRestrictedToAnnotationSession(), [$this, 'restrictToAnnotationSessionQuery'])
->when($this->isRestrictedToNewestLabel(), function ($query) {
return $this->restrictToNewestLabelQuery($query, 'video_annotation_labels');
return $this->restrictToNewestLabelQuery($query, $this->source);
})
->when($this->isRestrictedToLabels(), function ($query) {
return $this->restrictToLabelsQuery($query, 'video_annotation_labels');
Expand Down
2 changes: 1 addition & 1 deletion src/Support/Reports/Volumes/VideoIfdoReportGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ protected function query()
},
'annotations.labels' => function ($query) {
if ($this->isRestrictedToNewestLabel()) {
$query = $this->restrictToNewestLabelQuery($query, 'video_annotation_labels');
$query = $this->restrictToNewestLabelQuery($query, $this->source);
}

if ($this->isRestrictedToLabels()) {
Expand Down
38 changes: 25 additions & 13 deletions src/Traits/RestrictsToNewestLabels.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Biigle\Modules\Reports\Traits;

use Biigle\Modules\Reports\Volume;
use Biigle\Volume;
use DB;

trait RestrictsToNewestLabels
Expand All @@ -11,27 +11,39 @@ trait RestrictsToNewestLabels
* Callback to be used in a `when` query statement that restricts the results to the
* newest annotation labels of each annotation.
*
* @param \Illuminate\Database\Query\Builder $query
* @param string $table Name of the annotation label DB table
* @return \Illuminate\Database\Query\Builder
*/
public function restrictToNewestLabelQuery($query, $table)
public function restrictToNewestLabelQuery($query, Volume $volume)
{
// The subquery join is the fastest approach I could come up with that can be used
// as an addition to the existing query (instead of rewiriting the entire query,
// e.g. with a window function).
//
// Previously this was a where/in statement with was much slower.
//
// It could still be sped up with joins on image_annotations and images in the
// subquery, filtering it by volume_id, but this will be incompatible with video
// annotations. Maybe add a $mediaType argument to switch between tables?

$subquery = DB::table($table)
->selectRaw("distinct on (annotation_id) id")
->orderBy('annotation_id', 'desc')
->orderBy('id', 'desc')
->orderBy('created_at', 'desc');
if ($volume->isVideoVolume()) {
$table = 'video_annotation_labels';

$subquery = DB::table($table)
->selectRaw("distinct on (annotation_id) video_annotation_labels.id")
->join('video_annotations', 'video_annotations.id', '=', 'video_annotation_labels.annotation_id')
->join('videos', 'videos.id', '=', 'video_annotations.video_id')
->where('volume_id', $volume->id)
->orderBy('video_annotation_labels.annotation_id', 'desc')
->orderBy('video_annotation_labels.id', 'desc')
->orderBy('video_annotation_labels.created_at', 'desc');
} else {
$table = 'image_annotation_labels';

$subquery = DB::table($table)
->selectRaw("distinct on (annotation_id) image_annotation_labels.id")
->join('image_annotations', 'image_annotations.id', '=', 'image_annotation_labels.annotation_id')
->join('images', 'images.id', '=', 'image_annotations.image_id')
->where('volume_id', $volume->id)
->orderBy('image_annotation_labels.annotation_id', 'desc')
->orderBy('image_annotation_labels.id', 'desc')
->orderBy('image_annotation_labels.created_at', 'desc');
}

return $query->joinSub($subquery, 'latest_labels', fn ($join) => $join->on("{$table}.id", '=', 'latest_labels.id'));
}
Expand Down

0 comments on commit ce933bc

Please sign in to comment.