Quantcast
Channel: Transact-SQL forum
Viewing all articles
Browse latest Browse all 23857

How to speed up complex views

$
0
0

I have a view that calls on a series of other views to build a cumulative results report. The way that it is structured the view has run for 20 minutes without a result before I cancel it. 

Here is the final view:

SELECT TOP (100) PERCENT dbo.[Results Combined Nonpartisan].Ifc,
	dbo.[Results Combined Nonpartisan].[Group Type],
	dbo.[Results Combined Nonpartisan].Party,
	dbo.[Results Combined Nonpartisan].Contest,
	dbo.[Results Combined Nonpartisan].Candidate,
	SUM(dbo.[Results Combined Nonpartisan].Value) AS [Cumulative Value],
	dbo.[Results Combined Nonpartisan].DEFINITION,
	dbo.[Results Combined Nonpartisan].SetOrder,
	dbo.[Results Combined Nonpartisan].NAME AS ContestName,
	dbo.[Results Combined Nonpartisan].Sequence,
	dbo.[Results Combined Nonpartisan].[Vote For],
	dbo.[Over Under Cumulative].CumulativeUnder,
	dbo.[Over Under Cumulative].CumulativeOver,
	dbo.Candidates.NAME AS CandidateName,
	dbo.Candidates.Sequence AS CandidateSequence,
	dbo.[Results Combined Nonpartisan].PartyName
FROM dbo.[Results Combined Nonpartisan]
INNER JOIN dbo.[Over Under Cumulative] ON dbo.[Results Combined Nonpartisan].Contest = dbo.[Over Under Cumulative].Contest_Id
INNER JOIN dbo.Candidates ON dbo.[Results Combined Nonpartisan].Candidate = dbo.Candidates.Id
GROUP BY dbo.[Results Combined Nonpartisan].Party,
	dbo.[Results Combined Nonpartisan].Contest,
	dbo.[Results Combined Nonpartisan].Candidate,
	dbo.[Results Combined Nonpartisan].[Group Type],
	dbo.[Results Combined Nonpartisan].Ifc,
	dbo.[Results Combined Nonpartisan].DEFINITION,
	dbo.[Results Combined Nonpartisan].SetOrder,
	dbo.[Results Combined Nonpartisan].NAME,
	dbo.[Results Combined Nonpartisan].Sequence,
	dbo.[Results Combined Nonpartisan].[Vote For],
	dbo.[Over Under Cumulative].CumulativeUnder,
	dbo.[Over Under Cumulative].CumulativeOver,
	dbo.Candidates.NAME,
	dbo.Candidates.Sequence,
	dbo.[Results Combined Nonpartisan].PartyName
ORDER BY dbo.[Results Combined Nonpartisan].Ifc,
	dbo.[Results Combined Nonpartisan].[Group Type]


which calls: 

ALTER VIEW [dbo].[Results Combined Nonpartisan]
AS
SELECT [Ifc],
	[Party],
	[Contest],
	[Candidate],
	[Definition],
	[Group],
	[Value],
	[Group Type],
	[SetOrder],
	[Name],
	[Sequence],
	[Vote For],
	[PartyName]
FROM [TDG.Database].[dbo].[PartisanOnlyResults]

UNION ALL

SELECT [Ifc],
	[Contest],
	[Party],
	[Candidate],
	[Definition],
	[Group],
	[Value],
	[Group Type],
	[SetOrder],
	[Name],
	[Sequence],
	[Vote For],
	[PartyName]
FROM [TDG.Database].[dbo].[NonpartisanOnlyResults]

as well as:

ALTER VIEW [dbo].[Over Under Cumulative]
AS
SELECT TOP (100) PERCENT Ifc,
	[Group Type],
	[Group],
	Contest_Id,
	Contest,
	SUM(Undervotes) AS CumulativeUnder,
	SUM(Overvotes) AS CumulativeOver
FROM dbo.[Over Under Combined]
GROUP BY [Group Type],
	Contest_Id,
	Contest,
	Ifc,
	[Group]
ORDER BY Ifc,
	[Group Type],
	[Group],
	Contest_Id,
	Contest

[dbo].[Results Combined Nonpartisan] calls on:

ALTER VIEW [dbo].[PartisanOnlyResults]
AS
SELECT TOP (100) PERCENT ViewTable.Ifc,
	ViewTable.Party,
	ViewTable.Contest,
	ViewTable.Candidate,
	ViewTable.DEFINITION,
	ViewTable.[Group],
	SUM(CONVERT(INT, ViewTable.IsVoted)) AS Value,
	ViewTable.[Group Type],
	dbo.Parties.SetOrder,
	dbo.Contests.NAME,
	dbo.Contests.Sequence,
	dbo.Contests.[Vote For],
	dbo.Parties.NAME AS PartyName
FROM dbo.VotedPositions AS ViewTable
INNER JOIN dbo.Contests ON ViewTable.Contest = dbo.Contests.Id
INNER JOIN dbo.Parties ON dbo.Contests.Party = dbo.Parties.Id
WHERE (dbo.Parties.Nonpartisan = 0)
GROUP BY ViewTable.Ifc,
	ViewTable.Party,
	ViewTable.Contest,
	ViewTable.Candidate,
	ViewTable.DEFINITION,
	ViewTable.[Group],
	ViewTable.[Group Type],
	dbo.Parties.SetOrder,
	dbo.Contests.NAME,
	dbo.Contests.Sequence,
	dbo.Contests.[Vote For],
	dbo.Parties.NAME
GO

and: 

ALTER VIEW [dbo].[NonpartisanOnlyResults]
AS
SELECT TOP (100) PERCENT ViewTable.Ifc,
	ViewTable.Contest,
	dbo.Contests.Party,
	ViewTable.Candidate,
	ViewTable.DEFINITION,
	ViewTable.[Group],
	COUNT(CASE 
			WHEN [IsVoted] = 1
				THEN 1
			ELSE NULL
			END) AS Value,
	ViewTable.[Group Type],
	dbo.Parties.SetOrder,
	dbo.Contests.Sequence,
	dbo.Contests.[Vote For],
	dbo.Contests.NAME,
	dbo.Parties.NAME AS PartyName
FROM dbo.VotedPositions AS ViewTable
INNER JOIN dbo.Contests ON ViewTable.Contest = dbo.Contests.Id
INNER JOIN dbo.Parties ON dbo.Contests.Party = dbo.Parties.Id
WHERE (dbo.Parties.Nonpartisan = 1)
GROUP BY ViewTable.Ifc,
	ViewTable.Contest,
	ViewTable.Candidate,
	ViewTable.DEFINITION,
	ViewTable.[Group],
	ViewTable.[Group Type],
	dbo.Contests.Party,
	dbo.Parties.SetOrder,
	dbo.Contests.Sequence,
	dbo.Contests.[Vote For],
	dbo.Contests.NAME,
	dbo.Parties.NAME
ORDER BY ViewTable.DEFINITION,
	ViewTable.[Group],
	dbo.Contests.Party,
	ViewTable.Contest,
	ViewTable.Candidate
GO

Which ultimately calls on the source table which has just under 1 million rows. I have been working on this for the past few days and have tried numerous variations to speed this up. One of the attempts can even be seen above as I tried different methods to count the number of true values.

The source table (VotedPositions) is called multiple times, and I have a though that applying the filtering criteria to the source table before calling the other views could reduce the time, however I am uncertain how to accomplish this, or if it will matter.

Any insights would be greatly appreciated.



Viewing all articles
Browse latest Browse all 23857

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>