aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations
diff options
context:
space:
mode:
authorShadowghost <Ghost_of_Stone@web.de>2026-02-07 00:56:55 +0100
committerShadowghost <Ghost_of_Stone@web.de>2026-02-07 01:38:06 +0100
commit268d88a5fb8f0f71c96ba5abcef250d1f7e049ff (patch)
treedbca9e0725ed368f8621901b96a1f1a5846c500a /Emby.Server.Implementations
parent8ddc35a1ced32b40ef2ee333f2adcc57f3725811 (diff)
Optimize Collection Grouping, NextUp and Latest queries
Diffstat (limited to 'Emby.Server.Implementations')
-rw-r--r--Emby.Server.Implementations/Dto/DtoService.cs24
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs6
2 files changed, 25 insertions, 5 deletions
diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs
index e34e752da3..626f4ed0cd 100644
--- a/Emby.Server.Implementations/Dto/DtoService.cs
+++ b/Emby.Server.Implementations/Dto/DtoService.cs
@@ -185,10 +185,23 @@ namespace Emby.Server.Implementations.Dto
}
}
+ // Batch-fetch played/total counts for all folders to avoid N+1 queries
+ Dictionary<Guid, (int Played, int Total)>? playedCountBatch = null;
+ if (user is not null && options.EnableUserData)
+ {
+ var folderIds = accessibleItems.OfType<Folder>()
+ .Where(f => f.SupportsUserDataFromChildren && (f.SupportsPlayedStatus || options.ContainsField(ItemFields.RecursiveItemCount)))
+ .Select(f => f.Id).ToList();
+ if (folderIds.Count > 0)
+ {
+ playedCountBatch = _libraryManager.GetPlayedAndTotalCountBatch(folderIds, user);
+ }
+ }
+
for (int index = 0; index < accessibleItems.Count; index++)
{
var item = accessibleItems[index];
- var dto = GetBaseItemDtoInternal(item, options, user, owner, userDataBatch?.GetValueOrDefault(item.Id), allCollectionFolders, childCountBatch);
+ var dto = GetBaseItemDtoInternal(item, options, user, owner, userDataBatch?.GetValueOrDefault(item.Id), allCollectionFolders, childCountBatch, playedCountBatch);
if (item is LiveTvChannel tvChannel)
{
@@ -240,7 +253,7 @@ namespace Emby.Server.Implementations.Dto
return dto;
}
- private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, User? user = null, BaseItem? owner = null, UserItemData? userData = null, List<Folder>? allCollectionFolders = null, Dictionary<Guid, int>? childCountBatch = null)
+ private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, User? user = null, BaseItem? owner = null, UserItemData? userData = null, List<Folder>? allCollectionFolders = null, Dictionary<Guid, int>? childCountBatch = null, Dictionary<Guid, (int Played, int Total)>? playedCountBatch = null)
{
var dto = new BaseItemDto
{
@@ -277,7 +290,7 @@ namespace Emby.Server.Implementations.Dto
if (user is not null)
{
- AttachUserSpecificInfo(dto, item, user, options, userData, childCountBatch);
+ AttachUserSpecificInfo(dto, item, user, options, userData, childCountBatch, playedCountBatch);
}
if (item is IHasMediaSources
@@ -485,7 +498,7 @@ namespace Emby.Server.Implementations.Dto
/// <summary>
/// Attaches the user specific info.
/// </summary>
- private void AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, DtoOptions options, UserItemData? userData = null, Dictionary<Guid, int>? childCountBatch = null)
+ private void AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, DtoOptions options, UserItemData? userData = null, Dictionary<Guid, int>? childCountBatch = null, Dictionary<Guid, (int Played, int Total)>? playedCountBatch = null)
{
if (item.IsFolder)
{
@@ -497,7 +510,8 @@ namespace Emby.Server.Implementations.Dto
{
// Use pre-fetched user data
dto.UserData = GetUserItemDataDto(userData, item.Id);
- item.FillUserDataDtoValues(dto.UserData, userData, dto, user, options);
+ (int Played, int Total)? precomputed = playedCountBatch is not null && playedCountBatch.TryGetValue(item.Id, out var counts) ? counts : null;
+ item.FillUserDataDtoValues(dto.UserData, userData, dto, user, options, precomputed);
}
else
{
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 38aec6d491..29eda7d8b1 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -1515,6 +1515,12 @@ namespace Emby.Server.Implementations.Library
return _itemRepository.GetChildCountBatch(parentIds, userId);
}
+ /// <inheritdoc/>
+ public Dictionary<Guid, (int Played, int Total)> GetPlayedAndTotalCountBatch(IReadOnlyList<Guid> folderIds, User user)
+ {
+ return _itemRepository.GetPlayedAndTotalCountBatch(folderIds, user);
+ }
+
public IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents)
{
SetTopParentIdsOrAncestors(query, parents);