mirror of
https://github.com/stashapp/stash.git
synced 2025-12-06 16:34:02 +01:00
Omit joins that are only used for sorting when skipping sorting
Should provide some marginal improvement on systems with a lot of items.
This commit is contained in:
parent
7d96169796
commit
ff360ba5b1
7 changed files with 50 additions and 13 deletions
|
|
@ -96,6 +96,9 @@ type join struct {
|
|||
onClause string
|
||||
joinType string
|
||||
args []interface{}
|
||||
|
||||
// if true, indicates this is required for sorting only
|
||||
sort bool
|
||||
}
|
||||
|
||||
// equals returns true if the other join alias/table is equal to this one
|
||||
|
|
@ -131,9 +134,13 @@ type joins []join
|
|||
// returns true if added
|
||||
func (j *joins) addUnique(newJoin join) bool {
|
||||
found := false
|
||||
for _, jj := range *j {
|
||||
for i, jj := range *j {
|
||||
if jj.equals(newJoin) {
|
||||
found = true
|
||||
// if sort is false on the new join, but true on the existing, set the false
|
||||
if !newJoin.sort && jj.sort {
|
||||
(*j)[i].sort = false
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -151,13 +158,17 @@ func (j *joins) add(newJoins ...join) {
|
|||
}
|
||||
}
|
||||
|
||||
func (j *joins) toSQL() string {
|
||||
func (j *joins) toSQL(includeSortPagination bool) string {
|
||||
if len(*j) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
var ret []string
|
||||
for _, jj := range *j {
|
||||
// skip sort-only joins if not including sort/pagination
|
||||
if !includeSortPagination && jj.sort {
|
||||
continue
|
||||
}
|
||||
ret = append(ret, jj.toSQL())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -800,10 +800,12 @@ func (qb *GalleryStore) setGallerySort(query *queryBuilder, findFilter *models.F
|
|||
addFileTable := func() {
|
||||
query.addJoins(
|
||||
join{
|
||||
sort: true,
|
||||
table: galleriesFilesTable,
|
||||
onClause: "galleries_files.gallery_id = galleries.id",
|
||||
},
|
||||
join{
|
||||
sort: true,
|
||||
table: fileTable,
|
||||
onClause: "galleries_files.file_id = files.id",
|
||||
},
|
||||
|
|
@ -813,10 +815,12 @@ func (qb *GalleryStore) setGallerySort(query *queryBuilder, findFilter *models.F
|
|||
addFolderTable := func() {
|
||||
query.addJoins(
|
||||
join{
|
||||
sort: true,
|
||||
table: folderTable,
|
||||
onClause: "folders.id = galleries.folder_id",
|
||||
},
|
||||
join{
|
||||
sort: true,
|
||||
table: folderTable,
|
||||
as: "file_folder",
|
||||
onClause: "files.parent_folder_id = file_folder.id",
|
||||
|
|
|
|||
|
|
@ -518,7 +518,7 @@ func (qb *GroupStore) setGroupSort(query *queryBuilder, findFilter *models.FindF
|
|||
} else {
|
||||
// this will give unexpected results if the query is not filtered by a parent group and
|
||||
// the group has multiple parents and order indexes
|
||||
query.join(groupRelationsTable, "", "groups.id = groups_relations.sub_id")
|
||||
query.joinSort(groupRelationsTable, "", "groups.id = groups_relations.sub_id")
|
||||
query.sortAndPagination += getSort("order_index", direction, groupRelationsTable)
|
||||
}
|
||||
case "tag_count":
|
||||
|
|
|
|||
|
|
@ -965,10 +965,12 @@ func (qb *ImageStore) setImageSortAndPagination(q *queryBuilder, findFilter *mod
|
|||
addFilesJoin := func() {
|
||||
q.addJoins(
|
||||
join{
|
||||
sort: true,
|
||||
table: imagesFilesTable,
|
||||
onClause: "images_files.image_id = images.id",
|
||||
},
|
||||
join{
|
||||
sort: true,
|
||||
table: fileTable,
|
||||
onClause: "images_files.file_id = files.id",
|
||||
},
|
||||
|
|
@ -977,6 +979,7 @@ func (qb *ImageStore) setImageSortAndPagination(q *queryBuilder, findFilter *mod
|
|||
|
||||
addFolderJoin := func() {
|
||||
q.addJoins(join{
|
||||
sort: true,
|
||||
table: folderTable,
|
||||
onClause: "files.parent_folder_id = folders.id",
|
||||
})
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ type queryBuilder struct {
|
|||
sortAndPagination string
|
||||
}
|
||||
|
||||
func (qb queryBuilder) body() string {
|
||||
return fmt.Sprintf("SELECT %s FROM %s%s", strings.Join(qb.columns, ", "), qb.from, qb.joins.toSQL())
|
||||
func (qb queryBuilder) body(includeSortPagination bool) string {
|
||||
return fmt.Sprintf("SELECT %s FROM %s%s", strings.Join(qb.columns, ", "), qb.from, qb.joins.toSQL(includeSortPagination))
|
||||
}
|
||||
|
||||
func (qb *queryBuilder) addColumn(column string) {
|
||||
|
|
@ -33,7 +33,7 @@ func (qb *queryBuilder) addColumn(column string) {
|
|||
}
|
||||
|
||||
func (qb queryBuilder) toSQL(includeSortPagination bool) string {
|
||||
body := qb.body()
|
||||
body := qb.body(includeSortPagination)
|
||||
|
||||
withClause := ""
|
||||
if len(qb.withClauses) > 0 {
|
||||
|
|
@ -59,12 +59,14 @@ func (qb queryBuilder) findIDs(ctx context.Context) ([]int, error) {
|
|||
}
|
||||
|
||||
func (qb queryBuilder) executeFind(ctx context.Context) ([]int, int, error) {
|
||||
body := qb.body()
|
||||
const includeSortPagination = true
|
||||
body := qb.body(includeSortPagination)
|
||||
return qb.repository.executeFindQuery(ctx, body, qb.args, qb.sortAndPagination, qb.whereClauses, qb.havingClauses, qb.withClauses, qb.recursiveWith)
|
||||
}
|
||||
|
||||
func (qb queryBuilder) executeCount(ctx context.Context) (int, error) {
|
||||
body := qb.body()
|
||||
const includeSortPagination = false
|
||||
body := qb.body(includeSortPagination)
|
||||
|
||||
withClause := ""
|
||||
if len(qb.withClauses) > 0 {
|
||||
|
|
@ -131,6 +133,18 @@ func (qb *queryBuilder) join(table, as, onClause string) {
|
|||
qb.joins.add(newJoin)
|
||||
}
|
||||
|
||||
func (qb *queryBuilder) joinSort(table, as, onClause string) {
|
||||
newJoin := join{
|
||||
sort: true,
|
||||
table: table,
|
||||
as: as,
|
||||
onClause: onClause,
|
||||
joinType: "LEFT",
|
||||
}
|
||||
|
||||
qb.joins.add(newJoin)
|
||||
}
|
||||
|
||||
func (qb *queryBuilder) addJoins(joins ...join) {
|
||||
for _, j := range joins {
|
||||
if qb.joins.addUnique(j) {
|
||||
|
|
|
|||
|
|
@ -1157,10 +1157,12 @@ func (qb *SceneStore) setSceneSort(query *queryBuilder, findFilter *models.FindF
|
|||
addFileTable := func() {
|
||||
query.addJoins(
|
||||
join{
|
||||
sort: true,
|
||||
table: scenesFilesTable,
|
||||
onClause: "scenes_files.scene_id = scenes.id",
|
||||
},
|
||||
join{
|
||||
sort: true,
|
||||
table: fileTable,
|
||||
onClause: "scenes_files.file_id = files.id",
|
||||
},
|
||||
|
|
@ -1171,6 +1173,7 @@ func (qb *SceneStore) setSceneSort(query *queryBuilder, findFilter *models.FindF
|
|||
addFileTable()
|
||||
query.addJoins(
|
||||
join{
|
||||
sort: true,
|
||||
table: videoFileTable,
|
||||
onClause: "video_files.file_id = scenes_files.file_id",
|
||||
},
|
||||
|
|
@ -1180,6 +1183,7 @@ func (qb *SceneStore) setSceneSort(query *queryBuilder, findFilter *models.FindF
|
|||
addFolderTable := func() {
|
||||
query.addJoins(
|
||||
join{
|
||||
sort: true,
|
||||
table: folderTable,
|
||||
onClause: "files.parent_folder_id = folders.id",
|
||||
},
|
||||
|
|
@ -1189,10 +1193,10 @@ func (qb *SceneStore) setSceneSort(query *queryBuilder, findFilter *models.FindF
|
|||
direction := findFilter.GetDirection()
|
||||
switch sort {
|
||||
case "movie_scene_number":
|
||||
query.join(groupsScenesTable, "", "scenes.id = groups_scenes.scene_id")
|
||||
query.joinSort(groupsScenesTable, "", "scenes.id = groups_scenes.scene_id")
|
||||
query.sortAndPagination += getSort("scene_index", direction, groupsScenesTable)
|
||||
case "group_scene_number":
|
||||
query.join(groupsScenesTable, "scene_group", "scenes.id = scene_group.scene_id")
|
||||
query.joinSort(groupsScenesTable, "scene_group", "scenes.id = scene_group.scene_id")
|
||||
query.sortAndPagination += getSort("scene_index", direction, "scene_group")
|
||||
case "tag_count":
|
||||
query.sortAndPagination += getCountSort(sceneTable, scenesTagsTable, sceneIDColumn, direction)
|
||||
|
|
@ -1210,6 +1214,7 @@ func (qb *SceneStore) setSceneSort(query *queryBuilder, findFilter *models.FindF
|
|||
addFileTable()
|
||||
query.addJoins(
|
||||
join{
|
||||
sort: true,
|
||||
table: fingerprintTable,
|
||||
as: "fingerprints_phash",
|
||||
onClause: "scenes_files.file_id = fingerprints_phash.file_id AND fingerprints_phash.type = 'phash'",
|
||||
|
|
@ -1274,7 +1279,7 @@ func (qb *SceneStore) setSceneSort(query *queryBuilder, findFilter *models.FindF
|
|||
getSortDirection(direction),
|
||||
)
|
||||
case "studio":
|
||||
query.join(studioTable, "", "scenes.studio_id = studios.id")
|
||||
query.joinSort(studioTable, "", "scenes.studio_id = studios.id")
|
||||
query.sortAndPagination += getSort("name", direction, studioTable)
|
||||
default:
|
||||
query.sortAndPagination += getSort(sort, direction, "scenes")
|
||||
|
|
|
|||
|
|
@ -392,10 +392,10 @@ func (qb *SceneMarkerStore) setSceneMarkerSort(query *queryBuilder, findFilter *
|
|||
switch sort {
|
||||
case "scenes_updated_at":
|
||||
sort = "updated_at"
|
||||
query.join(sceneTable, "", "scenes.id = scene_markers.scene_id")
|
||||
query.joinSort(sceneTable, "", "scenes.id = scene_markers.scene_id")
|
||||
query.sortAndPagination += getSort(sort, direction, sceneTable)
|
||||
case "title":
|
||||
query.join(tagTable, "", "scene_markers.primary_tag_id = tags.id")
|
||||
query.joinSort(tagTable, "", "scene_markers.primary_tag_id = tags.id")
|
||||
query.sortAndPagination += " ORDER BY COALESCE(NULLIF(scene_markers.title,''), tags.name) COLLATE NATURAL_CI " + direction
|
||||
case "duration":
|
||||
sort = "(scene_markers.end_seconds - scene_markers.seconds)"
|
||||
|
|
|
|||
Loading…
Reference in a new issue