mirror of https://github.com/stashapp/stash.git
Improve performance of gallery and image queries (#2422)
* Revert to use FindByGalleryID in gallery resolver * Sort by path in FindByGalleryID * Optimise queries
This commit is contained in:
parent
2d227edaf9
commit
f581687198
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
`
|
||||
|
|
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 != "" {
|
||||
|
|
Loading…
Reference in New Issue