Postgres perf, path migration, and shutdown race fixes
- Major query performance boost: replaced correlated subqueries with DistinctBy() in BaseItemRepository, added episode deduplication index, and increased default command timeout to 120s. - Fixed LibraryMonitor shutdown race: added disposal checks and exception handling in FileRefresher to prevent ObjectDisposedException. - Added PowerShell and SQL utilities for fixing Linux paths in config files and database; new scripts for WebDir and path migration. - Auto-fix for WebDir in startup.json on load; new helper scripts and docs. - Added automated weekly DB performance monitoring scripts and reporting. - Expanded documentation and README for all fixes, scripts, and migration steps. - Updated SQL scripts for index creation and diagnostics; improved output handling. - Updated db-config defaults and added new diagnostic/report files.
This commit is contained in:
@@ -598,18 +598,20 @@ public sealed class BaseItemRepository
|
||||
var enableGroupByPresentationUniqueKey = EnableGroupByPresentationUniqueKey(filter);
|
||||
if (enableGroupByPresentationUniqueKey && filter.GroupBySeriesPresentationUniqueKey)
|
||||
{
|
||||
var tempQuery = dbQuery.GroupBy(e => new { e.PresentationUniqueKey, e.SeriesPresentationUniqueKey }).Select(e => e.FirstOrDefault()).Select(e => e!.Id);
|
||||
dbQuery = context.BaseItems.Where(e => tempQuery.Contains(e.Id));
|
||||
// PERFORMANCE FIX: Use DistinctBy() instead of GroupBy().Select().FirstOrDefault()
|
||||
// to prevent correlated subqueries. See docs/database-query-optimization.md
|
||||
dbQuery = dbQuery.DistinctBy(e => new { e.PresentationUniqueKey, e.SeriesPresentationUniqueKey });
|
||||
}
|
||||
else if (enableGroupByPresentationUniqueKey)
|
||||
{
|
||||
var tempQuery = dbQuery.GroupBy(e => e.PresentationUniqueKey).Select(e => e.FirstOrDefault()).Select(e => e!.Id);
|
||||
dbQuery = context.BaseItems.Where(e => tempQuery.Contains(e.Id));
|
||||
// PERFORMANCE FIX: Use DistinctBy() to generate DISTINCT ON instead of correlated subquery
|
||||
// This improves performance from 165s to <50ms. See docs/database-query-optimization.md
|
||||
dbQuery = dbQuery.DistinctBy(e => e.PresentationUniqueKey);
|
||||
}
|
||||
else if (filter.GroupBySeriesPresentationUniqueKey)
|
||||
{
|
||||
var tempQuery = dbQuery.GroupBy(e => e.SeriesPresentationUniqueKey).Select(e => e.FirstOrDefault()).Select(e => e!.Id);
|
||||
dbQuery = context.BaseItems.Where(e => tempQuery.Contains(e.Id));
|
||||
// PERFORMANCE FIX: Use DistinctBy() instead of GroupBy().Select().FirstOrDefault()
|
||||
dbQuery = dbQuery.DistinctBy(e => e.SeriesPresentationUniqueKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1659,10 +1661,11 @@ public sealed class BaseItemRepository
|
||||
ExcludeItemIds = filter.ExcludeItemIds
|
||||
};
|
||||
|
||||
// PERFORMANCE FIX: Use DistinctBy() instead of GroupBy().Select().FirstOrDefault()
|
||||
// to prevent correlated subqueries. Generates DISTINCT ON for PostgreSQL.
|
||||
var masterQuery = TranslateQuery(innerQuery, context, outerQueryFilter)
|
||||
.GroupBy(e => e.PresentationUniqueKey)
|
||||
.Select(e => e.FirstOrDefault())
|
||||
.Select(e => e!.Id);
|
||||
.DistinctBy(e => e.PresentationUniqueKey)
|
||||
.Select(e => e.Id);
|
||||
|
||||
var query = context.BaseItems
|
||||
.Include(e => e.TrailerTypes)
|
||||
@@ -1827,10 +1830,11 @@ public sealed class BaseItemRepository
|
||||
ExcludeItemIds = filter.ExcludeItemIds
|
||||
};
|
||||
|
||||
// PERFORMANCE FIX: Use DistinctBy() instead of GroupBy().Select().FirstOrDefault()
|
||||
// to prevent correlated subqueries. Generates DISTINCT ON for PostgreSQL.
|
||||
var masterQuery = TranslateQuery(innerQuery, context, outerQueryFilter)
|
||||
.GroupBy(e => e.PresentationUniqueKey)
|
||||
.Select(e => e.FirstOrDefault())
|
||||
.Select(e => e!.Id);
|
||||
.DistinctBy(e => e.PresentationUniqueKey)
|
||||
.Select(e => e.Id);
|
||||
|
||||
var query = context.BaseItems
|
||||
.Include(e => e.TrailerTypes)
|
||||
|
||||
Reference in New Issue
Block a user