PlotDirector/PlotLine/Sql/023_TimelinePerformanceIndexes.sql
2026-06-02 21:43:31 +01:00

143 lines
5.7 KiB
Transact-SQL

SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
/*
Timeline performance pass for imported/large projects.
Focus:
- Keep indexes narrow.
- Support the actual timeline/project load path.
- Avoid duplicating existing core indexes on Books, Chapters, Scenes,
PlotLines, StoryAssets, SceneCharacters(SceneID), AssetEvents(SceneID),
and ContinuityWarnings(ProjectID, BookID, SceneID...).
*/
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_ThreadEvents_PlotThreadID_SceneID' AND object_id = OBJECT_ID(N'dbo.ThreadEvents'))
BEGIN
-- Supports plot-thread filters and thread-event reads starting from a thread.
CREATE INDEX IX_ThreadEvents_PlotThreadID_SceneID
ON dbo.ThreadEvents(PlotThreadID, SceneID, EventTypeID);
END;
GO
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_AssetEvents_StoryAssetID_SceneID' AND object_id = OBJECT_ID(N'dbo.AssetEvents'))
BEGIN
-- Supports asset focus/filter lanes and asset-event reads starting from an asset.
CREATE INDEX IX_AssetEvents_StoryAssetID_SceneID
ON dbo.AssetEvents(StoryAssetID, SceneID, AssetEventTypeID);
END;
GO
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneCharacters_CharacterID_SceneID' AND object_id = OBJECT_ID(N'dbo.SceneCharacters'))
BEGIN
-- Supports character focus/filter lanes and character detail appearance lookups.
CREATE INDEX IX_SceneCharacters_CharacterID_SceneID
ON dbo.SceneCharacters(CharacterID, SceneID, RoleInSceneTypeID);
END;
GO
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_Characters_ProjectID_Importance_Name' AND object_id = OBJECT_ID(N'dbo.Characters'))
BEGIN
-- Supports CharacterTimeline_GetByProject ordering by importance, then name.
CREATE INDEX IX_Characters_ProjectID_Importance_Name
ON dbo.Characters(ProjectID, IsArchived, CharacterImportance DESC, CharacterName);
END;
GO
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_Locations_Project_Parent_Name' AND object_id = OBJECT_ID(N'dbo.Locations'))
BEGIN
-- Supports project location lists and LocationPaths roots by project.
CREATE INDEX IX_Locations_Project_Parent_Name
ON dbo.Locations(ProjectID, IsArchived, ParentLocationID, LocationName);
END;
GO
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_Locations_ParentLocationID' AND object_id = OBJECT_ID(N'dbo.Locations'))
BEGIN
-- Supports recursive LocationPaths expansion from parent to child locations.
CREATE INDEX IX_Locations_ParentLocationID
ON dbo.Locations(ParentLocationID, IsArchived, LocationName);
END;
GO
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneCharacters_LocationID_SceneID' AND object_id = OBJECT_ID(N'dbo.SceneCharacters'))
BEGIN
-- Supports timeline location filters that include character appearances at a location.
CREATE INDEX IX_SceneCharacters_LocationID_SceneID
ON dbo.SceneCharacters(LocationID, SceneID, CharacterID)
WHERE LocationID IS NOT NULL;
END;
GO
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneAssetLocations_LocationID_SceneID' AND object_id = OBJECT_ID(N'dbo.SceneAssetLocations'))
BEGIN
-- Supports timeline location filters that include assets placed at a location.
CREATE INDEX IX_SceneAssetLocations_LocationID_SceneID
ON dbo.SceneAssetLocations(LocationID, SceneID, StoryAssetID);
END;
GO
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneAssetLocations_SceneID_LocationID' AND object_id = OBJECT_ID(N'dbo.SceneAssetLocations'))
BEGIN
-- Supports scene-level location/asset reads from the scene inspector and timeline focus.
CREATE INDEX IX_SceneAssetLocations_SceneID_LocationID
ON dbo.SceneAssetLocations(SceneID, LocationID, StoryAssetID);
END;
GO
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_ContinuityWarnings_ActiveSceneCounts' AND object_id = OBJECT_ID(N'dbo.ContinuityWarnings'))
BEGIN
-- Supports active warning counts shown on timeline scene cards.
CREATE INDEX IX_ContinuityWarnings_ActiveSceneCounts
ON dbo.ContinuityWarnings(ProjectID, BookID, SceneID)
WHERE SceneID IS NOT NULL AND IsDismissed = 0 AND IsIntentional = 0;
END;
GO
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneDependencies_Project_SourceScene' AND object_id = OBJECT_ID(N'dbo.SceneDependencies'))
BEGIN
-- Supports dependency counts and source-scene dependency lookups.
CREATE INDEX IX_SceneDependencies_Project_SourceScene
ON dbo.SceneDependencies(ProjectID, IsArchived, SourceSceneID, TargetSceneID);
END;
GO
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneDependencies_Project_TargetScene' AND object_id = OBJECT_ID(N'dbo.SceneDependencies'))
BEGIN
-- Supports dependency counts and target-scene dependency lookups.
CREATE INDEX IX_SceneDependencies_Project_TargetScene
ON dbo.SceneDependencies(ProjectID, IsArchived, TargetSceneID, SourceSceneID);
END;
GO
CREATE OR ALTER PROCEDURE dbo.SceneDependency_Counts
@ProjectID int,
@BookID int = NULL
AS
BEGIN
SET NOCOUNT ON;
;WITH DependencyScenes AS
(
SELECT sd.SceneDependencyID, sd.SourceSceneID AS SceneID
FROM dbo.SceneDependencies sd
WHERE sd.ProjectID = @ProjectID AND sd.IsArchived = 0
UNION ALL
SELECT sd.SceneDependencyID, sd.TargetSceneID AS SceneID
FROM dbo.SceneDependencies sd
WHERE sd.ProjectID = @ProjectID
AND sd.IsArchived = 0
AND sd.TargetSceneID <> sd.SourceSceneID
)
SELECT scene.SceneID, COUNT(*) AS DependencyCount
FROM dbo.NarrativeSceneOrder scene
INNER JOIN DependencyScenes dependencyScene ON dependencyScene.SceneID = scene.SceneID
WHERE scene.ProjectID = @ProjectID AND (@BookID IS NULL OR scene.BookID = @BookID)
GROUP BY scene.SceneID;
END;
GO