Pārlūkot izejas kodu

Merge pull request #4653 from crobibero/favorite-persons

Optimize FavoritePersons query
Joshua M. Boniface 4 gadi atpakaļ
vecāks
revīzija
b96d4ef0e8

+ 10 - 13
Emby.Server.Implementations/Data/SqliteItemRepository.cs

@@ -5037,13 +5037,6 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
 
             var commandText = new StringBuilder("select Distinct p.Name from People p");
 
-            if (query.User != null && query.IsFavorite.HasValue)
-            {
-                commandText.Append(" LEFT JOIN TypedBaseItems tbi ON tbi.Name=p.Name AND tbi.Type='");
-                commandText.Append(typeof(Person).FullName);
-                commandText.Append("' LEFT JOIN UserDatas ON tbi.UserDataKey=key AND userId=@UserId");
-            }
-
             var whereClauses = GetPeopleWhereClauses(query, null);
 
             if (whereClauses.Count != 0)
@@ -5124,6 +5117,16 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
         {
             var whereClauses = new List<string>();
 
+            if (query.User != null && query.IsFavorite.HasValue)
+            {
+                whereClauses.Add(@"p.Name IN (
+SELECT Name FROM TypedBaseItems WHERE UserDataKey IN (
+SELECT key FROM UserDatas WHERE isFavorite=@IsFavorite AND userId=@UserId)
+AND Type = @InternalPersonType)");
+                statement?.TryBind("@IsFavorite", query.IsFavorite.Value);
+                statement?.TryBind("@InternalPersonType", typeof(Person).FullName);
+            }
+
             if (!query.ItemId.Equals(Guid.Empty))
             {
                 whereClauses.Add("ItemId=@ItemId");
@@ -5176,12 +5179,6 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
                 statement?.TryBind("@NameContains", "%" + query.NameContains + "%");
             }
 
-            if (query.IsFavorite.HasValue)
-            {
-                whereClauses.Add("isFavorite=@IsFavorite");
-                statement?.TryBind("@IsFavorite", query.IsFavorite.Value);
-            }
-
             if (query.User != null)
             {
                 statement?.TryBind("@UserId", query.User.InternalId);

+ 2 - 1
Jellyfin.Server/Migrations/MigrationRunner.cs

@@ -24,7 +24,8 @@ namespace Jellyfin.Server.Migrations
             typeof(Routines.MigrateUserDb),
             typeof(Routines.ReaddDefaultPluginRepository),
             typeof(Routines.MigrateDisplayPreferencesDb),
-            typeof(Routines.RemoveDownloadImagesInAdvance)
+            typeof(Routines.RemoveDownloadImagesInAdvance),
+            typeof(Routines.AddPeopleQueryIndex)
         };
 
         /// <summary>

+ 49 - 0
Jellyfin.Server/Migrations/Routines/AddPeopleQueryIndex.cs

@@ -0,0 +1,49 @@
+using System;
+using System.IO;
+using MediaBrowser.Controller;
+using Microsoft.Extensions.Logging;
+using SQLitePCL.pretty;
+
+namespace Jellyfin.Server.Migrations.Routines
+{
+    /// <summary>
+    /// Migration to add table indexes to optimize the Persons query.
+    /// </summary>
+    public class AddPeopleQueryIndex : IMigrationRoutine
+    {
+        private const string DbFilename = "library.db";
+        private readonly ILogger<AddPeopleQueryIndex> _logger;
+        private readonly IServerApplicationPaths _serverApplicationPaths;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="AddPeopleQueryIndex"/> class.
+        /// </summary>
+        /// <param name="logger">Instance of the <see cref="ILogger{AddPeopleQueryIndex}"/> interface.</param>
+        /// <param name="serverApplicationPaths">Instance of the <see cref="IServerApplicationPaths"/> interface.</param>
+        public AddPeopleQueryIndex(ILogger<AddPeopleQueryIndex> logger, IServerApplicationPaths serverApplicationPaths)
+        {
+            _logger = logger;
+            _serverApplicationPaths = serverApplicationPaths;
+        }
+
+        /// <inheritdoc />
+        public Guid Id => new Guid("DE009B59-BAAE-428D-A810-F67762DC05B8");
+
+        /// <inheritdoc />
+        public string Name => "AddPeopleQueryIndex";
+
+        /// <inheritdoc />
+        public bool PerformOnNewInstall => true;
+
+        /// <inheritdoc />
+        public void Perform()
+        {
+            var databasePath = Path.Join(_serverApplicationPaths.DataPath, DbFilename);
+            using var connection = SQLite3.Open(databasePath, ConnectionFlags.ReadWrite, null);
+            _logger.LogInformation("Creating index idx_TypedBaseItemsUserDataKeyType");
+            connection.Execute("CREATE INDEX idx_TypedBaseItemsUserDataKeyType ON TypedBaseItems(UserDataKey, Type);");
+            _logger.LogInformation("Creating index idx_PeopleNameListOrder");
+            connection.Execute("CREATE INDEX idx_PeopleNameListOrder ON People(Name, ListOrder);");
+        }
+    }
+}