Les services de diffusion musicale auto-hébergés subissent souvent une augmentation non linéaire de latence lors des paginations profondes et des agrégations complexes sur de larges catalogues. Afin de documenter les caractéristiques réelles de fonctionnement, nous avons conduit des mesures approfondies sur les chemins de lecture Subsonic de PureStream avec un jeu de test de 500 000 titres.
Périmètre des mesures et constitution des données
Les bibliothèques de passionnés atteignent couramment plusieurs centaines de milliers de pistes. Les principaux points d’entrée du protocole Subsonic (énumération search3, navigation getMusicDirectory, grille d’albums getAlbumList2) présentent des profils de coût très distincts selon le volume de données. Certains bénéficient d’index couvrants tandis que d’autres exigent des déduplications complètes. Cette session de test a concrétisé les étapes suivantes :
- [x] Création d’un catalogue de test de 500 000 enregistrements (~42 000 albums, 2 000 artistes, 100 genres) via le cycle de migration pour reproduire une base SQLite équivalente à la production
- [x] Implémentation d’un index de lecture couvrant pour les requêtes de genre et intégration au contrat de schéma pour éviter toute omission
- [x] Collecte des temps de latence P50 et P95 sur 14 chemins de lecture clés afin d’établir un rapport de référence
Métriques des chemins de lecture principaux
| Point d’entrée | 100k | 500k | Évaluation |
|---|---|---|---|
| search3 énumération principale | 53µs | 69µs | Stable |
| search3 page profonde (offset=250k) | — | 25ms | Stable |
| getMusicDirectory page unique | 1.3ms | 1.4ms | Stable |
| getAlbumList2 trois modes de pagination | 8–82ms | 86–333µs | Stable |
| getSongsByGenre | non mesuré | 113µs | Index efficace |
| FTS recherche textuelle | 24.8ms | 137ms | Progression linéaire |
| getArtists déduplication | 3.4ms | 543ms | Charge d’agrégation |
| getGenres agrégation | non mesuré | 600ms | Conforme aux attentes |
| Grand répertoire unique (page profonde) | — | 734ms | Cas limite |
Constats majeurs :
- Énumération principale (69 µs) : La requête par défaut search3 conserve un temps de réponse de l’ordre de la microseconde à 500 000 lignes. Elle s’appuie sur un index couvrant partiel ciblant les entrées valides, isolant ainsi la lecture des écritures de fond du scanner.
- Pagination en profondeur (25 ms) : L’extraction d’une page au décalage de 250 000 morceaux requiert 25 millisecondes, garantissant une navigation réactive en millisecondes.
- Filtrage par genre (113 µs) : L’index couvrant transforme le plan d’exécution d’un balayage de table en une recherche par index, réduisant significativement la durée globale.
Analyse des goulots de calcul
Le banc d’essai a mis en évidence deux scénarios d’agrégation exigeants en ressources :
- getArtists déduplication (543 ms) : La fusion des colonnes d’artistes principaux et secondaires implique des balayages sur l’ensemble de la table. Avec 500 000 morceaux, l’opération reste sous la seconde et fait l’objet d’un suivi technique.
- getGenres agrégation (600 ms) : Le calcul du nombre d’albums uniques via
COUNT(DISTINCT album)demande environ 600 millisecondes à l’échelle de 500 000 pistes.
Livrables de l’itération
- [x] Référence de performance P50/P95 pour 14 points d’accès sur 500 000 pistes
- [x] Déploiement de l’index de lecture pour les genres avec validation de schéma et tests de plans de requête
- [x] Quantification des points d’effort sur les regroupements pour orienter les développements futurs
Prochaines étapes
- [ ] Évolution de la pagination : Introduction d’une navigation par curseur sur les points d’entrée sans paramètre d’offset
- [ ] Regroupement des vérifications de session lors de la diffusion en cours
