mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-09 02:47:29 +02:00
perf(pglite): purge unused tags with EXCEPT, the NOT EXISTS form was still per-row
The CTE placed inside NOT EXISTS is correlated and re-evaluated for every tag row, so it was as slow as NOT IN on the real library (still running after 10 minutes). id IN (SELECT id FROM tag EXCEPT <used ids>) builds the unused set once with a hash set-op: about 1 s at 1M tag references, with or without planner statistics.
This commit is contained in:
parent
ec37e23718
commit
7922e93c75
1 changed files with 13 additions and 13 deletions
|
|
@ -82,20 +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).
|
||||
// EXCEPT builds the unused set once; NOT IN / a correlated NOT EXISTS re-evaluate the ~1M-row
|
||||
// used-tags subquery per tag row (minutes instead of ~1 s).
|
||||
del := Delete(r.tableName).Where(`
|
||||
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)
|
||||
id in (select id from ` + r.tableName + `
|
||||
except
|
||||
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
|
||||
except
|
||||
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)
|
||||
`)
|
||||
c, err := r.executeSQL(del)
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue