diff options
| author | Bond-009 <bond.009@outlook.com> | 2026-07-20 08:17:38 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-07-20 08:17:38 +0200 |
| commit | 236db6d2f6332373759c309c5ec722b1e416aa59 (patch) | |
| tree | c30d7e9ead7a961f49365c581fcb88a8f722f42f | |
| parent | 181c057cb8cca857585505f010034e462b9b094e (diff) | |
| parent | cdf7ce0fc4504eda29a2b4060fbe1fe628e2ee0a (diff) | |
Merge pull request #17365 from Shadowghost/fix-resume-perf
Fix Resume query performance
3 files changed, 14 insertions, 5 deletions
diff --git a/Emby.Server.Implementations/Library/UserDataManager.cs b/Emby.Server.Implementations/Library/UserDataManager.cs index 40cd2bb69c..19b42a3a11 100644 --- a/Emby.Server.Implementations/Library/UserDataManager.cs +++ b/Emby.Server.Implementations/Library/UserDataManager.cs @@ -291,8 +291,8 @@ namespace Emby.Server.Implementations.Library { using var dbContext = _repository.CreateDbContext(); withLocalAlternates = dbContext.LinkedChildren - .Where(lc => lc.ChildType == Jellyfin.Database.Implementations.Entities.LinkedChildType.LocalAlternateVersion - && localProbeIds.Contains(lc.ParentId)) + .Where(lc => lc.ChildType == Jellyfin.Database.Implementations.Entities.LinkedChildType.LocalAlternateVersion) + .WhereOneOrMany(localProbeIds, lc => lc.ParentId) .Select(lc => lc.ParentId) .Distinct() .ToHashSet(); diff --git a/Jellyfin.Server.Implementations/Item/BaseItemRepository.TranslateQuery.cs b/Jellyfin.Server.Implementations/Item/BaseItemRepository.TranslateQuery.cs index 52cebccc37..1198f99473 100644 --- a/Jellyfin.Server.Implementations/Item/BaseItemRepository.TranslateQuery.cs +++ b/Jellyfin.Server.Implementations/Item/BaseItemRepository.TranslateQuery.cs @@ -557,8 +557,13 @@ public sealed partial class BaseItemRepository : baseQuery.Where(e => inProgressIds.Contains(e.Id)); // When several versions of the same item are in progress, keep only the most recently played one, use id as tiebreaker. + // Only in-progress siblings can eliminate a candidate: a version without progress has a NULL max LastPlayedDate, + // which is never greater and never ties. Restricting the sibling scan to the in-progress set keeps this bounded by + // the user's Continue Watching count instead of forcing a full BaseItems scan (COALESCE keys are non-indexable) per row. baseQuery = baseQuery.Where(e => e.Type == seriesTypeName || !context.BaseItems - .Where(s => s.Id != e.Id && (s.PrimaryVersionId ?? s.Id) == (e.PrimaryVersionId ?? e.Id)) + .Where(s => s.Id != e.Id + && inProgressIds.Contains(s.Id) + && (s.PrimaryVersionId ?? s.Id) == (e.PrimaryVersionId ?? e.Id)) .Any(s => inProgress.Where(su => su.ItemId == s.Id).Max(su => su.LastPlayedDate) > inProgress.Where(eu => eu.ItemId == e.Id).Max(eu => eu.LastPlayedDate) diff --git a/tests/Jellyfin.Server.Implementations.Tests/Item/AlternateVersionQueryTranslationTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Item/AlternateVersionQueryTranslationTests.cs index c8aa14af58..b7fca74310 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Item/AlternateVersionQueryTranslationTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Item/AlternateVersionQueryTranslationTests.cs @@ -60,7 +60,9 @@ public sealed class AlternateVersionQueryTranslationTests : IDisposable .Where(e => seededIds.Contains(e.Id)) .Where(e => inProgressIds.Contains(e.Id)) .Where(e => !ctx.BaseItems - .Where(s => s.Id != e.Id && (s.PrimaryVersionId ?? s.Id) == (e.PrimaryVersionId ?? e.Id)) + .Where(s => s.Id != e.Id + && inProgressIds.Contains(s.Id) + && (s.PrimaryVersionId ?? s.Id) == (e.PrimaryVersionId ?? e.Id)) .Any(s => inProgress.Where(su => su.ItemId == s.Id).Max(su => su.LastPlayedDate) > inProgress.Where(eu => eu.ItemId == e.Id).Max(eu => eu.LastPlayedDate) @@ -110,7 +112,9 @@ public sealed class AlternateVersionQueryTranslationTests : IDisposable .Where(e => seededIds.Contains(e.Id)) .Where(e => inProgressIds.Contains(e.Id)) .Where(e => !ctx.BaseItems - .Where(s => s.Id != e.Id && (s.PrimaryVersionId ?? s.Id) == (e.PrimaryVersionId ?? e.Id)) + .Where(s => s.Id != e.Id + && inProgressIds.Contains(s.Id) + && (s.PrimaryVersionId ?? s.Id) == (e.PrimaryVersionId ?? e.Id)) .Any(s => inProgress.Where(su => su.ItemId == s.Id).Max(su => su.LastPlayedDate) > inProgress.Where(eu => eu.ItemId == e.Id).Max(eu => eu.LastPlayedDate) |
