Optimize studio filter on performers (#1515)

This commit is contained in:
gitgiggety 2021-06-21 06:17:43 +02:00 committed by GitHub
parent 86bd993b60
commit d7439b4832
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -458,80 +458,53 @@ func performerGalleryCountCriterionHandler(qb *performerQueryBuilder, count *mod
func performerStudiosCriterionHandler(studios *models.HierarchicalMultiCriterionInput) criterionHandlerFunc { func performerStudiosCriterionHandler(studios *models.HierarchicalMultiCriterionInput) criterionHandlerFunc {
return func(f *filterBuilder) { return func(f *filterBuilder) {
if studios != nil { if studios != nil {
var countCondition string var clauseCondition string
var clauseJoin string
if studios.Modifier == models.CriterionModifierIncludes { if studios.Modifier == models.CriterionModifierIncludes {
// return performers who appear in scenes/images/galleries with any of the given studios // return performers who appear in scenes/images/galleries with any of the given studios
countCondition = " > 0" clauseCondition = "NOT"
clauseJoin = " OR "
} else if studios.Modifier == models.CriterionModifierExcludes { } else if studios.Modifier == models.CriterionModifierExcludes {
// exclude performers who appear in scenes/images/galleries with any of the given studios // exclude performers who appear in scenes/images/galleries with any of the given studios
countCondition = " = 0" clauseCondition = ""
clauseJoin = " AND "
} else { } else {
return return
} }
inBinding := getInBinding(len(studios.Value))
formatMaps := []utils.StrFormatMap{ formatMaps := []utils.StrFormatMap{
{ {
"primaryTable": sceneTable, "primaryTable": sceneTable,
"joinTable": performersScenesTable, "joinTable": performersScenesTable,
"primaryFK": sceneIDColumn, "primaryFK": sceneIDColumn,
"inBinding": inBinding,
}, },
{ {
"primaryTable": imageTable, "primaryTable": imageTable,
"joinTable": performersImagesTable, "joinTable": performersImagesTable,
"primaryFK": imageIDColumn, "primaryFK": imageIDColumn,
"inBinding": inBinding,
}, },
{ {
"primaryTable": galleryTable, "primaryTable": galleryTable,
"joinTable": performersGalleriesTable, "joinTable": performersGalleriesTable,
"primaryFK": galleryIDColumn, "primaryFK": galleryIDColumn,
"inBinding": inBinding,
}, },
} }
// keeping existing behaviour for depth = 0 since it seems slightly better performing const derivedStudioTable = "studio"
if studios.Depth == 0 { const derivedPerformerStudioTable = "performer_studio"
templStr := `(SELECT COUNT(DISTINCT {primaryTable}.id) FROM {primaryTable} addHierarchicalWithClause(f, studios.Value, derivedStudioTable, studioTable, "parent_id", studios.Depth)
LEFT JOIN {joinTable} ON {primaryTable}.id = {joinTable}.{primaryFK}
WHERE {joinTable}.performer_id = performers.id AND {primaryTable}.studio_id IN {inBinding})` + countCondition
var clauses []string templStr := `SELECT performer_id FROM {primaryTable}
for _, c := range formatMaps { INNER JOIN {joinTable} ON {primaryTable}.id = {joinTable}.{primaryFK}
clauses = append(clauses, utils.StrFormat(templStr, c)) INNER JOIN studio ON {primaryTable}.studio_id = studio.child_id`
}
var args []interface{} var unions []string
for _, tagID := range studios.Value { for _, c := range formatMaps {
args = append(args, tagID) unions = append(unions, utils.StrFormat(templStr, c))
}
// this is a bit gross. We need the args three times
combinedArgs := append(args, append(args, args...)...)
f.addWhere(fmt.Sprintf("(%s)", strings.Join(clauses, clauseJoin)), combinedArgs...)
} else {
const derivedTable = "studio"
addHierarchicalWithClause(f, studios.Value, derivedTable, studioTable, "parent_id", studios.Depth)
templStr := `(SELECT COUNT(DISTINCT {primaryTable}.id) FROM {primaryTable}
LEFT JOIN {joinTable} ON {primaryTable}.id = {joinTable}.{primaryFK}
INNER JOIN studio ON {primaryTable}.studio_id = studio.child_id
WHERE {joinTable}.performer_id = performers.id)` + countCondition
var clauses []string
for _, c := range formatMaps {
clauses = append(clauses, utils.StrFormat(templStr, c))
}
f.addWhere(fmt.Sprintf("(%s)", strings.Join(clauses, clauseJoin)))
} }
f.addWith(fmt.Sprintf("%s AS (%s)", "performer_studio", strings.Join(unions, " UNION ")))
f.addJoin(derivedPerformerStudioTable, "", fmt.Sprintf("performers.id = %s.performer_id", derivedPerformerStudioTable))
f.addWhere(fmt.Sprintf("%s.performer_id IS %s NULL", derivedPerformerStudioTable, clauseCondition))
} }
} }
} }