Skip to content

Commit

Permalink
Improve performance of gallery and image queries (#2422)
Browse files Browse the repository at this point in the history
* Revert to use FindByGalleryID in gallery resolver
* Sort by path in FindByGalleryID
* Optimise queries
  • Loading branch information
WithoutPants authored Mar 25, 2022
1 parent 2d227ed commit f581687
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 12 deletions.
10 changes: 7 additions & 3 deletions internal/api/resolver_model_gallery.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ func (r *galleryResolver) Images(ctx context.Context, obj *models.Gallery) (ret
var err error

// #2376 - sort images by path
ret, err = image.FindByGalleryID(repo.Image(), obj.ID, "path", models.SortDirectionEnumAsc)
// doing this via Query is really slow, so stick with FindByGalleryID
ret, err = repo.Image().FindByGalleryID(obj.ID)
if err != nil {
return err
}

return err
}); err != nil {
Expand All @@ -40,8 +44,8 @@ func (r *galleryResolver) Images(ctx context.Context, obj *models.Gallery) (ret

func (r *galleryResolver) Cover(ctx context.Context, obj *models.Gallery) (ret *models.Image, err error) {
if err := r.withReadTxn(ctx, func(repo models.ReaderRepository) error {
// #2376 - use first image (sorted by path) if no cover is present
imgs, err := image.FindByGalleryID(repo.Image(), obj.ID, "path", models.SortDirectionEnumAsc)
// doing this via Query is really slow, so stick with FindByGalleryID
imgs, err := repo.Image().FindByGalleryID(obj.ID)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/sqlite/gallery.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func (qb *galleryQueryBuilder) FindBySceneID(sceneID int) ([]*models.Gallery, er

func (qb *galleryQueryBuilder) FindByImageID(imageID int) ([]*models.Gallery, error) {
query := selectAll(galleryTable) + `
LEFT JOIN galleries_images as images_join on images_join.gallery_id = galleries.id
INNER JOIN galleries_images as images_join on images_join.gallery_id = galleries.id
WHERE images_join.image_id = ?
GROUP BY galleries.id
`
Expand Down
11 changes: 8 additions & 3 deletions pkg/sqlite/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,12 @@ func (qb *imageQueryBuilder) FindByPath(path string) (*models.Image, error) {

func (qb *imageQueryBuilder) FindByGalleryID(galleryID int) ([]*models.Image, error) {
args := []interface{}{galleryID}
return qb.queryImages(imagesForGalleryQuery+qb.getImageSort(nil), args)
sort := "path"
sortDir := models.SortDirectionEnumAsc
return qb.queryImages(imagesForGalleryQuery+qb.getImageSort(&models.FindFilterType{
Sort: &sort,
Direction: &sortDir,
}), args)
}

func (qb *imageQueryBuilder) CountByGalleryID(galleryID int) (int, error) {
Expand Down Expand Up @@ -413,8 +418,8 @@ func imageTagCountCriterionHandler(qb *imageQueryBuilder, tagCount *models.IntCr

func imageGalleriesCriterionHandler(qb *imageQueryBuilder, galleries *models.MultiCriterionInput) criterionHandlerFunc {
addJoinsFunc := func(f *filterBuilder) {
qb.galleriesRepository().join(f, "galleries_join", "images.id")
f.addLeftJoin(galleryTable, "", "galleries_join.gallery_id = galleries.id")
qb.galleriesRepository().join(f, "", "images.id")
f.addLeftJoin(galleryTable, "", "galleries_images.gallery_id = galleries.id")
}
h := qb.getMultiCriterionHandlerBuilder(galleryTable, galleriesImagesTable, galleryIDColumn, addJoinsFunc)

Expand Down
4 changes: 2 additions & 2 deletions pkg/sqlite/scene.go
Original file line number Diff line number Diff line change
Expand Up @@ -713,8 +713,8 @@ func sceneStudioCriterionHandler(qb *sceneQueryBuilder, studios *models.Hierarch

func sceneMoviesCriterionHandler(qb *sceneQueryBuilder, movies *models.MultiCriterionInput) criterionHandlerFunc {
addJoinsFunc := func(f *filterBuilder) {
qb.moviesRepository().join(f, "movies_join", "scenes.id")
f.addLeftJoin("movies", "", "movies_join.movie_id = movies.id")
qb.moviesRepository().join(f, "", "scenes.id")
f.addLeftJoin("movies", "", "movies_scenes.movie_id = movies.id")
}
h := qb.getMultiCriterionHandlerBuilder(movieTable, moviesScenesTable, "movie_id", addJoinsFunc)
return h.handler(movies)
Expand Down
15 changes: 12 additions & 3 deletions pkg/sqlite/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,20 @@ func getMultiCriterionClause(primaryTable, foreignTable, joinTable, primaryFK, f
switch criterion.Modifier {
case models.CriterionModifierIncludes:
// includes any of the provided ids
whereClause = foreignTable + ".id IN " + getInBinding(len(criterion.Value))
if joinTable != "" {
whereClause = joinTable + "." + foreignFK + " IN " + getInBinding(len(criterion.Value))
} else {
whereClause = foreignTable + ".id IN " + getInBinding(len(criterion.Value))
}
case models.CriterionModifierIncludesAll:
// includes all of the provided ids
whereClause = foreignTable + ".id IN " + getInBinding(len(criterion.Value))
havingClause = "count(distinct " + foreignTable + ".id) IS " + strconv.Itoa(len(criterion.Value))
if joinTable != "" {
whereClause = joinTable + "." + foreignFK + " IN " + getInBinding(len(criterion.Value))
havingClause = "count(distinct " + joinTable + "." + foreignFK + ") IS " + strconv.Itoa(len(criterion.Value))
} else {
whereClause = foreignTable + ".id IN " + getInBinding(len(criterion.Value))
havingClause = "count(distinct " + foreignTable + ".id) IS " + strconv.Itoa(len(criterion.Value))
}
case models.CriterionModifierExcludes:
// excludes all of the provided ids
if joinTable != "" {
Expand Down

0 comments on commit f581687

Please sign in to comment.