Tuesday, 1 October 2013

CURSOR OR UNION ALL - UNION ALL IS SLOW

CURSOR OR UNION ALL - UNION ALL IS SLOW

Have a query that I run on the first of the month that goes against 6
databases.. Problem is that when run, it takes upward of 3 hours to run.
Thinking about this, I could do this with either a UNION ALL with PIVOT -
which is what is used today.. Or I could do a CURSOR from master do loop
through the databases on the server. But, I have to ask myself, how
efficient is this query?
SELECT *
FROM (
SELECT
'db1' AS DB
,YEAR(dateadd(hh,-5,ETIME)) as [YEAR]
,LEFT(DATENAME(MONTH, dateadd(hh,-5,ETIME)), 3) AS MONTH
,CASE WHEN ID IS NULL THEN 'NoTYPE' ELSE 'TYPE' END AS 'TYPE'
,ACT
,COUNT(ACT) AS Amount
FROM DB1.dbo.LOG (nolock) JOIN
DB1.dbo.TABL (nolock) ON DB1.dbo.LOG.ID = DB1.dbo.TABL.NAME COLLATE
SQL_Latin1_General_CP1_CI_AS
--WHERE dateadd(hh,-5,ETIME) >
dateadd(MM,-3,dateadd(day,datediff(day,0,getdate()),0))
GROUP BY YEAR(dateadd(hh,-5,ETIME))
, LEFT(DATENAME(MONTH, dateadd(hh,-5,ETIME)), 3)
, CASE WHEN ID IS NULL THEN 'NoTYPE' ELSE 'TYPE' END
, DB1.dbo.LOG.ACT
UNION ALL
-- next db.. AND 4 FOUR MORE..
) as s
PIVOT
(
SUM(Amount)
FOR [month] IN (JAN, FEB, MAR, APR,
MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC)
)
as PVT
Then we are doing the same thing by quarter..
SELECT *
FROM (
SELECT
'db1' AS DB
, YEAR(DATEADD(hh, - 5, DB1.dbo.LOG.ETIME)) AS YEAR
, DATEPART(q, DB1.dbo.LOG.ETIME) AS QUARTER
,CASE WHEN ID IS NULL THEN 'NoTYPE' ELSE 'TYPE' END AS 'TYPE'
,ACT
,COUNT(ACT) AS Amount
FROM DB1.dbo.LOG (nolock) JOIN
DB1.dbo.TABL (nolock) ON DB1.dbo.LOG.ID = DB1.dbo.TABL.NAME COLLATE
SQL_Latin1_General_CP1_CI_AS
GROUP BY YEAR(DB1.dbo.LOG.ETIME)
, DATEPART(q, DB1.dbo.LOG.ETIME)
, DB1.dbo.LOG.ACT
, YEAR(DATEADD(hh, - 5, DB1.dbo.ETIME))
UNION ALL
-- next db.. AND 4 FOUR MORE..
) as s
PIVOT
(
sum(Amount)
FOR [quarter] IN ([1], [2], [3], [4])
)
as PVT
Thanks,
Kent

No comments:

Post a Comment