February 12, 2008 at 3:11 pm
If I do a select * from dbo.v_department it takes 1 minute and 40 seconds to run.
It has run in a second or 2 at times but lately it's slow and a cpu hog.
Any ideas?
This is also on a VMWare vm.
thanks
this is the v_department view:
SELECT DepartmentID, DepartmentName, AgencyName, ShortName, CreatedOn, Status, UpdatedOn, UpdatedBy, CASE WHEN
(SELECT COUNT(z.DepartmentID)
FROM tblDepartment AS z LEFT JOIN
tblFooter AS b ON a.departmentid = b.departmentid LEFT JOIN
tblHeader AS c ON a.departmentid = c.departmentid LEFT JOIN
tblLogo AS d ON a.departmentid = d .departmentid LEFT JOIN
tblPressRelease AS e ON a.departmentid = e.departmentid LEFT JOIN
tblUser AS f ON a.departmentID = f.departmentID
WHERE a.DepartmentID = z.DepartmentID) > 1 THEN 'N' ELSE 'Y' END AS DeleteOK, CASE WHEN
(SELECT COUNT(z.DepartmentID)
FROM tblDepartment AS z LEFT JOIN
tblFooter AS b ON a.departmentid = b.departmentid LEFT JOIN
tblHeader AS c ON a.departmentid = c.departmentid LEFT JOIN
tblLogo AS d ON a.departmentid = d .departmentid LEFT JOIN
tblPressRelease AS e ON a.departmentid = e.departmentid LEFT JOIN
tblUser AS f ON a.departmentID = f.departmentID
WHERE a.DepartmentID = z.DepartmentID AND b.Status = 1 OR
c.Status = 1 OR
d .Status = 1 OR
e.Archived = 0 OR
f.Status = 1) > 1 THEN 'N' ELSE 'Y' END AS InactivateOK
FROM dbo.tblDepartment AS a
February 12, 2008 at 3:32 pm
Did you already check to make sure the indexes on the tables being queried are in place? Did you look at the execution plan?
February 12, 2008 at 3:44 pm
I just verified that the indexes(clustered) exist. I don't know what an execution plan is? I'm new to being a dba.
Also, If I run a select query and instead of using *, I select all the columns except the DeleteOK and InactivateOK fields, it runs fast.
thanks
February 12, 2008 at 3:51 pm
Well - it looks to me that you have 2 correlated sub-queries, and one is substantially more complicated than it needs to be (gut-feeling - not proof).
How about this as a rewrite:
SELECT DepartmentID, DepartmentName, AgencyName, ShortName, CreatedOn, Status, UpdatedOn, UpdatedBy,
CASE WHEN delOK.delcount > 1 THEN 'N' ELSE 'Y' END AS DeleteOK,
CASE WHEN inactOK.inact > 1 THEN 'N' ELSE 'Y' END AS InactivateOK
FROM dbo.tblDepartment AS a
left outer join
(
SELECT
z.DepartmentID,
COUNT(*) as delcount
FROM tblDepartment as z
LEFT JOIN tblFooter AS b ON z.departmentid = b.departmentid
LEFT JOIN tblHeader AS c ON z.departmentid = c.departmentid
LEFT JOIN tblLogo AS d ON z.departmentid = d .departmentid
LEFT JOIN tblPressRelease AS e ON z.departmentid = e.departmentid
LEFT JOIN tblUser AS f ON z.departmentID = f.departmentID
group by departmentid
) as delOk on a.DepartmentID = delOK.DepartmentID
left outer join
(
SELECT z.departmentid, COUNT(*) as inact
FROM tblDepartment AS z LEFT JOIN
tblFooter AS b ON z.departmentid = b.departmentid LEFT JOIN
tblHeader AS c ON z.departmentid = c.departmentid LEFT JOIN
tblLogo AS d ON z.departmentid = d .departmentid LEFT JOIN
tblPressRelease AS e ON z.departmentid = e.departmentid LEFT JOIN
tblUser AS f ON z.departmentID = f.departmentID
WHEREb.Status = 1 OR
c.Status = 1 OR
d .Status = 1 OR
e.Archived = 0 OR
f.Status = 1
group by z.departmentid
) as InactOk on a.DepartmentID = InactOk.DepartmentID
Voila - 2 derived tables instead. Should work somewhat better. You need some good indexes on all of this stuff.
----------------------------------------------------------------------------------
Your lack of planning does not constitute an emergency on my part...unless you're my manager...or a director and above...or a really loud-spoken end-user..All right - what was my emergency again?
February 12, 2008 at 4:58 pm
Rewrite # 2
SELECT DepartmentID, DepartmentName, AgencyName, ShortName, CreatedOn, Status, UpdatedOn, UpdatedBy,
CASE WHEN delOK.delcount > 1 THEN 'N' ELSE 'Y' END AS DeleteOK,
CASE WHEN delOK.inact > 1 THEN 'N' ELSE 'Y' END AS InactivateOK
FROM dbo.tblDepartment AS a
left outer join
(
SELECT
z.DepartmentID,
COUNT(*) as delcount,
sum(case when b.Status = 1
OR c.Status = 1
OR d .Status = 1
OR e.Archived = 0
OR f.Status = 1
then 1 else 0 end) as inact
FROM tblDepartment as z
LEFT JOIN tblFooter AS b ON z.departmentid = b.departmentid
LEFT JOIN tblHeader AS c ON z.departmentid = c.departmentid
LEFT JOIN tblLogo AS d ON z.departmentid = d .departmentid
LEFT JOIN tblPressRelease AS e ON z.departmentid = e.departmentid
LEFT JOIN tblUser AS f ON z.departmentID = f.departmentID
group by departmentid
) as delOk on a.DepartmentID = delOK.DepartmentID
And then there was just one (derived table)
----------------------------------------------------------------------------------
Your lack of planning does not constitute an emergency on my part...unless you're my manager...or a director and above...or a really loud-spoken end-user..All right - what was my emergency again?
February 12, 2008 at 5:48 pm
Heh... proof again... performance is in the code... water cooled CPU's wouldn't have made that query run any faster.
Nice job, Matt.
--Jeff Moden
Change is inevitable... Change for the better is not.
February 13, 2008 at 9:25 am
Thanks y'all.
Awesome!
February 14, 2008 at 6:51 am
What is the purpose of
sum(case when b.Status = 1 OR c.Status = 1 OR d .Status = 1 OR e.Archived = 0 OR f.Status = 1 then 1 else 0 end) as inact
For here ?
Thanks.
February 14, 2008 at 7:15 am
Sorry, I don't know. I'm a system dba and don't know much about this view as it was created by on of our developers. We had noticed it was running slow so that's why I posted this thread.
thanks
February 14, 2008 at 9:52 am
Learn to use the tuning advisor - BUT just don't blindly do whatever it suggests because it will not take into account all the many things going on outside the query it is checking. It usually will get you quickly pointed in the right direction to make some improvements with complicated queries. The tuning advisor saves time in basic analysis but you'll have to know when not to add all the indexes it suggests because that may cause other problems, especially when loading.
February 14, 2008 at 9:59 am
Frances L (2/14/2008)
What is the purpose ofsum(case when b.Status = 1 OR c.Status = 1 OR d .Status = 1 OR e.Archived = 0 OR f.Status = 1 then 1 else 0 end) as inact
For here ?
Thanks.
It's doing a "conditional count". In other words - it's counting the number of times those criteria are met.
Interestingly enough, you could probably re-write it to be
count(case when b.Status = 1
OR c.Status = 1
OR d .Status = 1
OR e.Archived = 0
OR f.Status = 1 then 1 else NULL end) as inact
but this relies (I think) on the ANSI_NULLS setting, so I dont use this method.
----------------------------------------------------------------------------------
Your lack of planning does not constitute an emergency on my part...unless you're my manager...or a director and above...or a really loud-spoken end-user..All right - what was my emergency again?
February 14, 2008 at 10:02 am
that is my thought ,too. but I do not know I can't use sum this way. Thx. I looked at bol and google conditional count , not that much come out . It might be undocumented way.
Viewing 12 posts - 1 through 11 (of 11 total)
You must be logged in to reply to this topic. Login to reply