Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Query tuning...

Author  Topic 

Ramkumar
Starting Member

2 Posts

Posted - 2006-07-13 : 02:05:51
The below given view runs for 520 seconds to returnd 50432 rows. is there an way this can be tuned???
In this query, same table is joined more than once. what is the use of doing this?

SELECT 'STORE' AS SETID
,D.TREE_NODE AS DEPTID
,A.TREE_NODE AS DEPTID_FILTR
,J.DESCR AS MS_RPT_TREE_DEPT
,H.DESCR AS MS_RPT_TREE_PRNT
,I.DESCR AS MS_RPT_TREE_GRND
,D.TREE_LEVEL_NUM AS 'CHILD_LEVEL'
,F.TREE_NODE AS 'REPORTS_TO_DEPT'
,A.TREE_LEVEL_NUM AS 'PARENT_LEVEL_NUM'
FROM PSTREENODE A -- 65595 rows
,PSTREENODE D
,PSTREENODE F
,PS_DEPT_TBL H -- 18132 rows
,PS_DEPT_TBL I
,PS_DEPT_TBL J
,PSTREENODE G
WHERE A.TREE_NAME = 'DEPT_SECURITY'
AND A.SETID = 'STORE'
AND D.TREE_NAME = A.TREE_NAME
AND D.SETID = A.SETID
AND D.EFFDT = A.EFFDT
AND D.TREE_NODE_NUM BETWEEN (SELECT B.TREE_NODE_NUM
FROM PSTREENODE B
WHERE B.TREE_NODE = A.TREE_NODE
AND B.TREE_NAME = A.TREE_NAME
AND B.EFFDT = A.EFFDT
AND B.SETID = A.SETID)
AND (SELECT C.TREE_NODE_NUM_END
FROM PSTREENODE C
WHERE C.TREE_NODE = A.TREE_NODE
AND C.TREE_NAME = A.TREE_NAME
AND C.EFFDT = A.EFFDT
AND C.SETID = A.SETID)
AND D.TREE_LEVEL_NUM BETWEEN 3 AND 6
AND A.EFFDT = (SELECT MAX(TD.EFFDT)
FROM PSTREEDEFN TD
WHERE TD.SETID = A.SETID
AND TD.TREE_NAME = A.TREE_NAME
AND TD.EFFDT <= CONVERT(CHAR(10), GETDATE(), 110))
AND F.TREE_NAME = D.TREE_NAME
AND F.SETID = D.SETID
AND F.EFFDT = D.EFFDT
AND F.TREE_NODE_NUM = D.PARENT_NODE_NUM
AND G.TREE_NAME = D.TREE_NAME
AND G.SETID = D.SETID
AND G.EFFDT = D.EFFDT
AND G.TREE_NODE_NUM = F.PARENT_NODE_NUM
AND F.TREE_NODE = H.DEPTID
AND H.SETID = A.SETID
AND H.EFFDT = (SELECT MAX(C_EFFDT.EFFDT)
FROM PS_DEPT_TBL C_EFFDT
WHERE C_EFFDT.SETID = H.SETID
AND C_EFFDT.DEPTID = H.DEPTID
AND C_EFFDT.EFFDT <= SUBSTRING(CONVERT(CHAR,GETDATE()),1,11))
AND G.TREE_NODE = I.DEPTID
AND I.SETID = A.SETID
AND I.EFFDT = (SELECT MAX(C_EFFDT.EFFDT)
FROM PS_DEPT_TBL C_EFFDT
WHERE C_EFFDT.SETID = I.SETID
AND C_EFFDT.DEPTID = I.DEPTID
AND C_EFFDT.EFFDT <= SUBSTRING(CONVERT(CHAR,GETDATE()),1,11))
AND D.TREE_NODE = J.DEPTID
AND J.SETID = A.SETID
AND J.EFFDT = (SELECT MAX(C_EFFDT.EFFDT)
FROM PS_DEPT_TBL C_EFFDT
WHERE C_EFFDT.SETID = J.SETID
AND C_EFFDT.DEPTID = J.DEPTID
AND C_EFFDT.EFFDT <= SUBSTRING(CONVERT(CHAR,GETDATE()),1,11))
AND A.SETCNTRLVALUE = ' '
AND D.SETCNTRLVALUE = A.SETCNTRLVALUE
AND F.SETCNTRLVALUE = A.SETCNTRLVALUE
AND G.SETCNTRLVALUE = A.SETCNTRLVALUE


PS_DEPT_TBL
-----------
PS0DEPT_TBL nonclustered located on PRIMARY DESCR, SETID, DEPTID, EFFDT
PS1DEPT_TBL nonclustered located on PRIMARY COMPANY, SETID, DEPTID, EFFDT
PS2DEPT_TBL nonclustered located on PRIMARY SETID_LOCATION, SETID, DEPTID, EFFDT
PS3DEPT_TBL nonclustered located on PRIMARY LOCATION, SETID, DEPTID, EFFDT
PS4DEPT_TBL nonclustered located on PRIMARY BUDGET_DEPTID, SETID, DEPTID, EFFDT
PS_DEPT_TBL clustered, unique located on PRIMARY SETID, DEPTID, EFFDT

PSTREENODE
----------
PSAPSTREENODE nonclustered located on PRIMARY SETID, TREE_NAME, EFFDT, TREE_BRANCH, TREE_NODE, TREE_NODE_NUM, TREE_NODE_NUM_END, TREE_NODE_TYPE
PSBPSTREENODE nonclustered located on PRIMARY SETID, TREE_NAME, TREE_BRANCH, TREE_NODE_NUM, TREE_NODE, TREE_NODE_NUM_END, TREE_LEVEL_NUM, TREE_NODE_TYPE
PSCPSTREENODE nonclustered located on PRIMARY TREE_NODE
PSDPSTREENODE nonclustered located on PRIMARY SETID, TREE_NAME, EFFDT, PARENT_NODE_NUM
PSFPSTREENODE nonclustered located on PRIMARY TREE_NAME, EFFDT
PS_PSTREENODE clustered, unique located on PRIMARY SETID, SETCNTRLVALUE, TREE_NAME, EFFDT, TREE_NODE_NUM, TREE_NODE, TREE_BRANCH

When i read the execution plan, it showed 2 Index pools (costing 38%) on

WHERE B.TREE_NODE = A.TREE_NODE
AND B.TREE_NAME = A.TREE_NAME
AND B.EFFDT = A.EFFDT
AND B.SETID = A.SETID

and

WHERE C.TREE_NODE = A.TREE_NODE
AND C.TREE_NAME = A.TREE_NAME
AND C.EFFDT = A.EFFDT
AND C.SETID = A.SETID

is there any way i can avoid this index pool or tune thi query?


Thanks and Regards,
Ramkumar Murugesan

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2006-07-13 : 06:44:25
Well, using six subqueries and several joins to the same table multiple times tends to take time when querying. Also not using normalized tables does that.

I believe you are stuck with this query until something dramatic happens to your table definitions. Self-joining a table is a way to handle hierarchies.

I have rewritten your query to ANSI 92 SQL syntax and this is how it looks. You can see that it is either very complex, or the developer had no clue how to solve his problem.
SELECT		'STORE' AS SETID,
D.TREE_NODE AS DEPTID,
A.TREE_NODE AS DEPTID_FILTR,
J.DESCR AS MS_RPT_TREE_DEPT,
H.DESCR AS MS_RPT_TREE_PRNT,
I.DESCR AS MS_RPT_TREE_GRND,
D.TREE_LEVEL_NUM AS 'CHILD_LEVEL',
F.TREE_NODE AS 'REPORTS_TO_DEPT',
A.TREE_LEVEL_NUM AS 'PARENT_LEVEL_NUM'
FROM PSTREENODE A
INNER JOIN PSTREENODE D ON D.SETCNTRLVALUE = A.SETCNTRLVALUE AND D.TREE_NAME = A.TREE_NAME AND D.SETID = A.SETID AND D.EFFDT = A.EFFDT
INNER JOIN PSTREENODE F ON F.SETCNTRLVALUE = A.SETCNTRLVALUE AND F.TREE_NAME = D.TREE_NAME AND F.SETID = D.SETID AND F.EFFDT = D.EFFDT AND F.TREE_NODE_NUM = D.PARENT_NODE_NUM
INNER JOIN PSTREENODE G ON G.SETCNTRLVALUE = A.SETCNTRLVALUE AND G.TREE_NAME = F.TREE_NAME AND G.SETID = F.SETID AND G.EFFDT = F.EFFDT AND G.TREE_NODE_NUM = F.PARENT_NODE_NUM
INNER JOIN PS_DEPT_TBL H ON H.DEPTID = F.TREE_NODE AND H.SETID = A.SETID
INNER JOIN PS_DEPT_TBL I ON I.SETID = A.SETID AND I.DEPTID = G.TREE_NODE
INNER JOIN PS_DEPT_TBL J ON J.DEPTID = D.TREE_NODE AND J.SETID = A.SETID
WHERE A.TREE_NAME = 'DEPT_SECURITY'
AND A.SETID = 'STORE'
AND A.SETCNTRLVALUE = ' '
AND D.TREE_LEVEL_NUM BETWEEN 3 AND 6
AND D.TREE_NODE_NUM BETWEEN (
SELECT B.TREE_NODE_NUM
FROM PSTREENODE B
WHERE B.TREE_NODE = A.TREE_NODE
AND B.TREE_NAME = A.TREE_NAME
AND B.EFFDT = A.EFFDT
AND B.SETID = A.SETID
) AND
(
SELECT C.TREE_NODE_NUM_END
FROM PSTREENODE C
WHERE C.TREE_NODE = A.TREE_NODE
AND C.TREE_NAME = A.TREE_NAME
AND C.EFFDT = A.EFFDT
AND C.SETID = A.SETID
)
AND A.EFFDT = ( SELECT MAX(TD.EFFDT)
FROM PSTREEDEFN TD
WHERE TD.SETID = A.SETID
AND TD.TREE_NAME = A.TREE_NAME
AND TD.EFFDT <= CONVERT(CHAR(10), GETDATE(), 110)
)
AND H.EFFDT = (
SELECT MAX(C_EFFDT.EFFDT)
FROM PS_DEPT_TBL C_EFFDT
WHERE C_EFFDT.SETID = H.SETID
AND C_EFFDT.DEPTID = H.DEPTID
AND C_EFFDT.EFFDT <= SUBSTRING(CONVERT(CHAR, GETDATE()), 1, 11)
)
AND I.EFFDT = (
SELECT MAX(C_EFFDT.EFFDT)
FROM PS_DEPT_TBL C_EFFDT
WHERE C_EFFDT.SETID = I.SETID
AND C_EFFDT.DEPTID = I.DEPTID
AND C_EFFDT.EFFDT <= SUBSTRING(CONVERT(CHAR, GETDATE()), 1, 11)
)
AND J.EFFDT = (
SELECT MAX(C_EFFDT.EFFDT)
FROM PS_DEPT_TBL C_EFFDT
WHERE C_EFFDT.SETID = J.SETID
AND C_EFFDT.DEPTID = J.DEPTID
AND C_EFFDT.EFFDT <= SUBSTRING(CONVERT(CHAR,GETDATE()), 1, 11)
)

Peter Larsson
Helsingborg, Sweden
Go to Top of Page

Ramkumar
Starting Member

2 Posts

Posted - 2006-07-13 : 07:58:33
just out of curiosity i ask this question... how did you find that the tables are not normalized?

Thanks and Regards,
Ramkumar Murugesan
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2006-07-13 : 09:35:28
Multiple join arguments between tables.
Also see [url]http://www.datamodel.org/NormalizationRules.html[/url].


Peter Larsson
Helsingborg, Sweden
Go to Top of Page
   

- Advertisement -