Fixed: Slow db migration when upgrading from v2 to v3 with a large collection

This commit is contained in:
Taloth Saldono 2019-05-10 23:08:31 +02:00
parent 83c09b4540
commit 9e68653949
1 changed files with 65 additions and 52 deletions

View File

@ -1,9 +1,12 @@
using System.Data; using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using FluentMigrator; using FluentMigrator;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Migration.Framework;
using NzbDrone.Core.Datastore.Converters; using NzbDrone.Core.Datastore.Converters;
using NzbDrone.Core.Languages; using NzbDrone.Core.Languages;
using System;
namespace NzbDrone.Core.Datastore.Migration namespace NzbDrone.Core.Datastore.Migration
{ {
@ -28,6 +31,31 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
var LanguageConverter = new EmbeddedDocumentConverter(new LanguageIntConverter()); var LanguageConverter = new EmbeddedDocumentConverter(new LanguageIntConverter());
var profileLanguages = new Dictionary<int, int>();
using (IDbCommand getProfileCmd = conn.CreateCommand())
{
getProfileCmd.Transaction = tran;
getProfileCmd.CommandText = "SELECT Id, Language FROM Profiles";
IDataReader profilesReader = getProfileCmd.ExecuteReader();
while (profilesReader.Read())
{
var profileId = profilesReader.GetInt32(0);
var episodeLanguage = Language.English.Id;
try
{
episodeLanguage = profilesReader.GetInt32(1);
}
catch (InvalidCastException e)
{
_logger.Debug("Language field not found in Profiles, using English as default." + e.Message);
}
profileLanguages[profileId] = episodeLanguage;
}
}
var seriesLanguages = new Dictionary<int, int>();
using (IDbCommand getSeriesCmd = conn.CreateCommand()) using (IDbCommand getSeriesCmd = conn.CreateCommand())
{ {
getSeriesCmd.Transaction = tran; getSeriesCmd.Transaction = tran;
@ -39,59 +67,44 @@ namespace NzbDrone.Core.Datastore.Migration
var seriesId = seriesReader.GetInt32(0); var seriesId = seriesReader.GetInt32(0);
var seriesProfileId = seriesReader.GetInt32(1); var seriesProfileId = seriesReader.GetInt32(1);
using (IDbCommand getProfileCmd = conn.CreateCommand()) seriesLanguages[seriesId] = profileLanguages.GetValueOrDefault(seriesProfileId, Language.English.Id);
{
getProfileCmd.Transaction = tran;
getProfileCmd.CommandText = "SELECT Language FROM Profiles WHERE Id = ?";
getProfileCmd.AddParameter(seriesProfileId);
IDataReader profilesReader = getProfileCmd.ExecuteReader();
while (profilesReader.Read())
{
var episodeLanguage = Language.English.Id;
try
{
episodeLanguage = profilesReader.GetInt32(0);
} catch (InvalidCastException e)
{
_logger.Debug("Language field not found in Profiles, using English as default." + e.Message);
}
var validJson = LanguageConverter.ToDB(Language.FindById(episodeLanguage));
using (IDbCommand updateEpisodeFilesCmd = conn.CreateCommand())
{
updateEpisodeFilesCmd.Transaction = tran;
updateEpisodeFilesCmd.CommandText = "UPDATE EpisodeFiles SET Language = ? WHERE SeriesId = ?";
updateEpisodeFilesCmd.AddParameter(validJson);
updateEpisodeFilesCmd.AddParameter(seriesId);
updateEpisodeFilesCmd.ExecuteNonQuery();
}
using (IDbCommand updateHistoryCmd = conn.CreateCommand())
{
updateHistoryCmd.Transaction = tran;
updateHistoryCmd.CommandText = "UPDATE History SET Language = ? WHERE SeriesId = ?";
updateHistoryCmd.AddParameter(validJson);
updateHistoryCmd.AddParameter(seriesId);
updateHistoryCmd.ExecuteNonQuery();
}
using (IDbCommand updateBlacklistCmd = conn.CreateCommand())
{
updateBlacklistCmd.Transaction = tran;
updateBlacklistCmd.CommandText = "UPDATE Blacklist SET Language = ? WHERE SeriesId = ?";
updateBlacklistCmd.AddParameter(validJson);
updateBlacklistCmd.AddParameter(seriesId);
updateBlacklistCmd.ExecuteNonQuery();
}
}
}
} }
} }
} }
foreach (var group in seriesLanguages.GroupBy(v => v.Value, v => v.Key))
{
var languageJson = LanguageConverter.ToDB(Language.FindById(group.Key));
var seriesIds = group.Select(v => v.ToString()).Join(",");
using (IDbCommand updateEpisodeFilesCmd = conn.CreateCommand())
{
updateEpisodeFilesCmd.Transaction = tran;
updateEpisodeFilesCmd.CommandText = $"UPDATE EpisodeFiles SET Language = ? WHERE SeriesId IN ({seriesIds})";
updateEpisodeFilesCmd.AddParameter(languageJson);
updateEpisodeFilesCmd.ExecuteNonQuery();
}
using (IDbCommand updateHistoryCmd = conn.CreateCommand())
{
updateHistoryCmd.Transaction = tran;
updateHistoryCmd.CommandText = $"UPDATE History SET Language = ? WHERE SeriesId IN ({seriesIds})";
updateHistoryCmd.AddParameter(languageJson);
updateHistoryCmd.ExecuteNonQuery();
}
using (IDbCommand updateBlacklistCmd = conn.CreateCommand())
{
updateBlacklistCmd.Transaction = tran;
updateBlacklistCmd.CommandText = $"UPDATE Blacklist SET Language = ? WHERE SeriesId IN ({seriesIds})";
updateBlacklistCmd.AddParameter(languageJson);
updateBlacklistCmd.ExecuteNonQuery();
}
}
} }
} }
} }