navidrome/core/playlists
Deluan Quintão dbd26ba2e7
perf(scanner): improve playlist importing on large libraries (#6055)
* perf(persistence): avoid a full media_file scan when resolving playlist paths

FindByPaths built one OR-ed equality term per path. On the real media_file
schema SQLite abandons the path index at just two OR-ed terms and falls back to
SCAN media_file, re-testing every term against every row, so the cost grows with
(rows x terms).

Group the candidates by library and emit one IN list per library instead, which
plans as SEARCH media_file USING INDEX media_file_path_nocase. The NOCASE
collation is kept so ASCII case-insensitive matching still works.

This is the dominant cost of M3U playlist import, which resolves every track on
every scan. Measured with a 1000-track playlist against a migrated DB:

  100k media_file rows:   397 -> 51,414 tracks/sec
  500k media_file rows:  78.5 -> 47,174 tracks/sec

The rate no longer degrades as the table grows, which is the expected shape for
an index lookup. Reported in #6043, where an 8 hour scan of a 2M-song library
spent 7h52m in the playlist phase.

* docs(playlists): correct the stale reason for the M3U lookup chunk size

The expression-tree depth ceiling applied to the old OR-per-path query, which
capped a batch at roughly 500 terms. The IN form is bound by SQLite's 32766
variable limit instead, which the 400 candidates per chunk sit far below.
2026-08-30 22:17:25 -04:00
..
import.go fix(playlist): preserve smart playlist song count on re-import (#5907) (#5908) 2026-08-18 20:58:55 -04:00
import_test.go fix(playlist): preserve smart playlist song count on re-import (#5907) (#5908) 2026-08-18 20:58:55 -04:00
parse_m3u.go perf(scanner): improve playlist importing on large libraries (#6055) 2026-08-30 22:17:25 -04:00
parse_m3u_test.go ci: run Go tests on Windows (#5380) 2026-04-19 13:16:47 -04:00
parse_nsp.go refactor: multiple syntax updates for Go 1.26 2026-05-19 18:02:36 -03:00
parse_nsp_test.go fix(smartplaylist): reject NSP mixing top-level 'any' and 'all' (#5759) 2026-07-10 20:27:29 -04:00
playlists.go fix(playlist): block track edits on synced playlists across all APIs (#5984) 2026-08-19 08:47:53 -04:00
playlists_suite_test.go refactor: move playlist business logic from repositories to service layer (#5027) 2026-02-21 19:57:13 -05:00
playlists_test.go fix(playlist): block track edits on synced playlists across all APIs (#5984) 2026-08-19 08:47:53 -04:00
rest_adapter.go fix(playlist): preserve smart playlist song count on re-import (#5907) (#5908) 2026-08-18 20:58:55 -04:00
rest_adapter_test.go fix(playlist): preserve smart playlist song count on re-import (#5907) (#5908) 2026-08-18 20:58:55 -04:00