mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-11 11:57:12 +02:00
perf(pglite): purge unused tags with NOT EXISTS instead of NOT IN
On a 97k-track library the tag purge in the scanner GC ran for many minutes: PostgreSQL re-evaluates a NOT IN subquery of ~1M tag references per tag row. A materialized set with NOT EXISTS takes 1.4 s locally versus 55 s for NOT IN at that scale; work_mem made no difference.
This commit is contained in:
parent
9ff44a6854
commit
ec37e23718
1 changed files with 13 additions and 9 deletions
|
|
@ -82,16 +82,20 @@ func (r *tagRepository) GetAll(name model.TagName, options ...model.QueryOptions
|
|||
}
|
||||
|
||||
func (r *tagRepository) purgeUnused() error {
|
||||
// NOT EXISTS over a materialized set: NOT IN re-scans the ~1M-row subquery per tag (40x slower).
|
||||
del := Delete(r.tableName).Where(`
|
||||
id not in (select elem->>'id'
|
||||
from album
|
||||
cross join lateral jsonb_each(coalesce(album.tags, '{}'::jsonb)) as e(k, arr)
|
||||
cross join lateral jsonb_array_elements(e.arr) as elem
|
||||
UNION
|
||||
select elem->>'id'
|
||||
from media_file
|
||||
cross join lateral jsonb_each(coalesce(media_file.tags, '{}'::jsonb)) as e(k, arr)
|
||||
cross join lateral jsonb_array_elements(e.arr) as elem)
|
||||
not exists (
|
||||
with used(id) as materialized (
|
||||
select elem->>'id'
|
||||
from album
|
||||
cross join lateral jsonb_each(coalesce(album.tags, '{}'::jsonb)) as e(k, arr)
|
||||
cross join lateral jsonb_array_elements(e.arr) as elem
|
||||
union
|
||||
select elem->>'id'
|
||||
from media_file
|
||||
cross join lateral jsonb_each(coalesce(media_file.tags, '{}'::jsonb)) as e(k, arr)
|
||||
cross join lateral jsonb_array_elements(e.arr) as elem)
|
||||
select 1 from used where used.id = ` + r.tableName + `.id)
|
||||
`)
|
||||
c, err := r.executeSQL(del)
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue