Selbst gehostete Musik-Streaming-Dienste weisen bei sehr großen Bibliotheken häufig deutliche Latenzanstiege bei tiefem Paging und komplexen Aggregationen auf. Um das reale Betriebsverhalten präzise zu erfassen, haben wir auf einem Referenzdatensatz mit 500.000 Titeln umfassende Latenzmessungen für die Subsonic-Lesepfade von PureStream durchgeführt.
Messrahmen und Datenaufbau
Die lokalen Musiksammlungen engagierter Nutzer umfassen regelmäßig mehrere hunderttausend Titel. Zentrale Subsonic-Endpunkte (darunter search3, Verzeichniszugriffe über getMusicDirectory und Albumübersichten via getAlbumList2) weisen bei wachsendem Datenvolumen stark unterschiedliche Kostenstrukturen auf. Manche Pfade profitieren von Covering Indexes, während andere vollständige Deduplizierungen erfordern. Im aktuellen Messdurchlauf wurden folgende Aufgaben umgesetzt:
- [x] Aufbau eines Testdatensatzes mit 500.000 Medienzeilen (~42.000 Alben, 2.000 Interpreten, 100 Genres) über die reguläre Migrationskette in einer produktionsnahen SQLite-Datenbank
- [x] Ergänzung eines Covering-Leseindex für Genre-Abfragen mit Verankerung in der Schemaprüfung zur Vermeidung von Indexverlusten
- [x] Ermittlung von P50- und P95-Latenzwerten über 14 zentrale Lesepfade zur Erstellung einer belastbaren Baseline
Messwerte der zentralen Lesepfade
| Endpunkt | 100k | 500k | Bewertung |
|---|---|---|---|
| search3 Hauptaufzählung | 53µs | 69µs | Stabil |
| search3 Deep Page (Offset=250k) | — | 25ms | Stabil |
| getMusicDirectory Einzelseite | 1.3ms | 1.4ms | Stabil |
| getAlbumList2 Drei Paging-Modi | 8–82ms | 86–333µs | Stabil |
| getSongsByGenre | nicht gemessen | 113µs | Index wirksam |
| FTS Volltextsuche | 24.8ms | 137ms | Linearer Anstieg |
| getArtists Deduplizierung | 3.4ms | 543ms | Aggregationslast |
| getGenres Aggregation | nicht gemessen | 600ms | Im Rahmen |
| Sehr großes Verzeichnis (Deep Page) | — | 734ms | Randfall |
Wesentliche Beobachtungen:
- Hauptaufzählung (69 µs): Die Standardabfrage von search3 bleibt auch bei 500.000 Datensätzen im Mikrosekundenbereich. Dies gelingt durch einen partiellen Covering Index auf aktive Zeilen, der Hintergrundaktualisierungen des Scanners von der Leseebene entkoppelt.
- Deep Paging (25 ms): Das Abrufen einer einzelnen Seite bei einem Versatz von 250.000 Titeln benötigt 25 Millisekunden und sichert eine flüssige Navigation im Millisekundenbereich.
- Genre-Filterung (113 µs): Durch den neuen Covering Index wechselt der Ausführungsplan von einem sequenziellen Tabellenscan zu einem Index-Scan, wodurch sich die Antwortzeit stark verkürzt.
Analyse von Rechenschwerpunkten
Die Messungen quantifizierten zwei rechenintensive Aggregationspfade:
- getArtists Deduplizierung (543 ms): Die Zusammenführung von Haupt- und Mitwirkenden-Interpreten erfordert Tabellenscans über den gesamten Datenbestand. Bei 500.000 Titeln bleibt die Ausführung unter einer Sekunde und wird im Monitoring geführt.
- getGenres Aggregation (600 ms): Die statistische Zählung eindeutiger Alben über
COUNT(DISTINCT album)beansprucht bei 500.000 Einträgen rund 600 Millisekunden.
Erzielte Ergebnisse
- [x] Vollständige P50/P95-Performance-Baseline für 14 zentrale Lesepfade auf 500.000 Titeln
- [x] Bereitstellung des Genre-Leseindex mit Schemaregistrierung und Ausführungsplantests
- [x] Quantifizierung rechenintensiver Hotspots zur Vorbereitung künftiger Optimierungen
Nächste Schritte
- [ ] Optimierung der Paginierung: Einführung von Cursor-basierter Navigation für Endpunkte ohne Offset-Parameter
- [ ] Konsolidierung von Authentifizierungsabfragen für laufende Streaming-Sitzungen
