diff options
| author | Shadowghost <Ghost_of_Stone@web.de> | 2026-03-07 20:14:04 +0100 |
|---|---|---|
| committer | Shadowghost <Ghost_of_Stone@web.de> | 2026-03-07 20:14:04 +0100 |
| commit | ea1c1d046856ab46e6bda1903c97702292e61ff9 (patch) | |
| tree | c8fd1b0e7078cfd938a9b5409309441a2cca2188 | |
| parent | 077fa89717957f871b172ca4b2dc4a178efd3bc5 (diff) | |
Optimize grouping query performance
| -rw-r--r-- | Jellyfin.Server.Implementations/Item/BaseItemRepository.QueryBuilding.cs | 8 | ||||
| -rw-r--r-- | Jellyfin.Server.Implementations/Item/BaseItemRepository.Querying.cs | 1 |
2 files changed, 6 insertions, 3 deletions
diff --git a/Jellyfin.Server.Implementations/Item/BaseItemRepository.QueryBuilding.cs b/Jellyfin.Server.Implementations/Item/BaseItemRepository.QueryBuilding.cs index d4cdfdbc3e..b1f7326d06 100644 --- a/Jellyfin.Server.Implementations/Item/BaseItemRepository.QueryBuilding.cs +++ b/Jellyfin.Server.Implementations/Item/BaseItemRepository.QueryBuilding.cs @@ -68,19 +68,21 @@ public sealed partial class BaseItemRepository // for that case the invoker has to run a DistinctBy(e => e.PresentationUniqueKey) on their own var enableGroupByPresentationUniqueKey = EnableGroupByPresentationUniqueKey(filter); + // Use Min(Id) instead of OrderBy(Id).FirstOrDefault() to avoid EF Core generating + // a correlated scalar subquery per group. if (enableGroupByPresentationUniqueKey && filter.GroupBySeriesPresentationUniqueKey) { - var tempQuery = dbQuery.GroupBy(e => new { e.PresentationUniqueKey, e.SeriesPresentationUniqueKey }).Select(e => e.OrderBy(x => x.Id).FirstOrDefault()).Select(e => e!.Id); + var tempQuery = dbQuery.GroupBy(e => new { e.PresentationUniqueKey, e.SeriesPresentationUniqueKey }).Select(e => e.Min(x => x.Id)); dbQuery = context.BaseItems.Where(e => tempQuery.Contains(e.Id)); } else if (enableGroupByPresentationUniqueKey) { - var tempQuery = dbQuery.GroupBy(e => e.PresentationUniqueKey).Select(e => e.OrderBy(x => x.Id).FirstOrDefault()).Select(e => e!.Id); + var tempQuery = dbQuery.GroupBy(e => e.PresentationUniqueKey).Select(e => e.Min(x => x.Id)); dbQuery = context.BaseItems.Where(e => tempQuery.Contains(e.Id)); } else if (filter.GroupBySeriesPresentationUniqueKey) { - var tempQuery = dbQuery.GroupBy(e => e.SeriesPresentationUniqueKey).Select(e => e.OrderBy(x => x.Id).FirstOrDefault()).Select(e => e!.Id); + var tempQuery = dbQuery.GroupBy(e => e.SeriesPresentationUniqueKey).Select(e => e.Min(x => x.Id)); dbQuery = context.BaseItems.Where(e => tempQuery.Contains(e.Id)); } else diff --git a/Jellyfin.Server.Implementations/Item/BaseItemRepository.Querying.cs b/Jellyfin.Server.Implementations/Item/BaseItemRepository.Querying.cs index 3487fa09d7..f1899cd2de 100644 --- a/Jellyfin.Server.Implementations/Item/BaseItemRepository.Querying.cs +++ b/Jellyfin.Server.Implementations/Item/BaseItemRepository.Querying.cs @@ -88,6 +88,7 @@ public sealed partial class BaseItemRepository } var itemsById = ApplyNavigations(context.BaseItems.Where(e => orderedIds.Contains(e.Id)), filter) + .AsSplitQuery() .AsEnumerable() .Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)) .Where(dto => dto != null) |
