Optimize search3, by removing OFFSET when paginating (#2655)
* Optimize pagination, removing offset * For search, don't add `where` clause for empty queries * Revert "Replace `COUNT(DISTINCT primary_key)` with `COUNT(*)`" Genres are required as part of the count queries, so filter by genres work * Optimize search3 query, using order by id if it is a "" query. Also fix the optimizePagination query logic * Allow offset optimizer threshold to be configured
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
. "github.com/Masterminds/squirrel"
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/google/uuid"
|
||||
"github.com/navidrome/navidrome/conf"
|
||||
"github.com/navidrome/navidrome/log"
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/model/request"
|
||||
@@ -157,7 +158,10 @@ func (r sqlRepository) queryOne(sq Sqlizer, response interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (r sqlRepository) queryAll(sq Sqlizer, response interface{}) error {
|
||||
func (r sqlRepository) queryAll(sq SelectBuilder, response interface{}, options ...model.QueryOptions) error {
|
||||
if len(options) > 0 && options[0].Offset > 0 {
|
||||
sq = r.optimizePagination(sq, options[0])
|
||||
}
|
||||
query, args, err := sq.ToSql()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -172,6 +176,19 @@ func (r sqlRepository) queryAll(sq Sqlizer, response interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// optimizePagination uses a less inefficient pagination, by not using OFFSET.
|
||||
// See https://gist.github.com/ssokolow/262503
|
||||
func (r sqlRepository) optimizePagination(sq SelectBuilder, options model.QueryOptions) SelectBuilder {
|
||||
if options.Offset > conf.Server.DevOffsetOptimize {
|
||||
sq = sq.RemoveOffset()
|
||||
oidSq := sq.RemoveColumns().Columns(r.tableName + ".oid")
|
||||
oidSq = oidSq.Limit(uint64(options.Offset))
|
||||
oidSql, args, _ := oidSq.ToSql()
|
||||
sq = sq.Where(r.tableName+".oid not in ("+oidSql+")", args...)
|
||||
}
|
||||
return sq
|
||||
}
|
||||
|
||||
func (r sqlRepository) exists(existsQuery SelectBuilder) (bool, error) {
|
||||
existsQuery = existsQuery.Columns("count(*) as exist").From(r.tableName)
|
||||
var res struct{ Exist int64 }
|
||||
|
||||
Reference in New Issue
Block a user