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
 SQL Server Development (2000)
 Here's a challenge for anyone!??

Author  Topic 

NickyJ
Starting Member

46 Posts

Posted - 2005-08-17 : 10:06:34
I have traced an T-SQL statement as a web page on a live production box is running slow and often timing out. The trace returned


"SELECT LtdCompany.LtdCompanyID, LtdCompany.Name,
LtdCompany.RegNumber, LtdCompany.VATNumber, LtdCompany.VATEffectiveDate,
LtdCompany.BankName, LtdCompany.Branch, LtdCompany.AccountName, LtdCompany.AccountNumber,
LtdCompany.BSRef, LtdCompany.SortCode, LtdCompany.isLtdCompany, Address.Address1,
Address.Address2, Address.Address3, Address.Address4, Address.Address5, Address.PostCode
FROM LtdCompany
INNER JOIN (SELECT DISTINCT A.LtdCompanyID FROM LtdCompany AS A WITH (NOLOCK)
INNER JOIN LtdCompany AS B WITH (NOLOCK) ON A.LtdCompanyIdentification = B.LtdCompanyIdentification
INNER JOIN LtdComContractor WITH (NOLOCK) ON B.LtdCompanyID = LtdComContractor.LtdCompanyID
INNER JOIN Contract WITH (NOLOCK) ON LtdComContractor.ContractID = Contract.ContractID AND Contract.ComLocationID
IN (2) ) AS LtdCom ON LtdCompany.LtdCompanyID = LtdCom.LtdCompanyID AND LtdCompany.Name LIKE 'l%'
INNER JOIN LtdComContractor WITH (NOLOCK) ON LtdCompany.LtdCompanyID = LtdComContractor.LtdCompanyID
AND (('2005/08/17' BETWEEN LtdComContractor.EffectiveDateFrom AND LtdComContractor.EffectiveDateTo)
OR ('2005/08/17' > LtdComContractor.EffectiveDateTo AND LtdCompany.isLatest = 1))
INNER JOIN LtdCompany AS LtdCom1 WITH (NOLOCK) ON LtdCompany.LtdCompanyIdentification = LtdCom1.LtdCompanyIdentification
INNER JOIN plcAddress WITH (NOLOCK) ON LtdCom1.LtdCompanyID = plcAddress.PlacementID
AND plcAddress.AddressType = 4 AND (('2005/08/17' BETWEEN plcAddress.EffectiveDateFrom
AND plcAddress.EffectiveDateTo) OR ('2005/08/17' >= plcAddress.EffectiveDateFrom
AND ISDATE(plcAddress.EffectiveDateTo) = 0))
INNER JOIN Address WITH (NOLOCK) ON plcAddress.AddressID = Address.AddressID
UNION SELECT LtdCompany.LtdCompanyID, LtdCompany.Name, LtdCompany.RegNumber, LtdCompany.VATNumber,
LtdCompany.VATEffectiveDate, LtdCompany.BankName, LtdCompany.Branch, LtdCompany.AccountName,
LtdCompany.AccountNumber, LtdCompany.BSRef, LtdCompany.SortCode, LtdCompany.isLtdCompany,
Address.Address1, Address.Address2, Address.Address3, Address.Address4, Address.Address5,
Address.PostCode FROM LtdCompany
INNER JOIN (SELECT DISTINCT A.LtdCompanyID FROM LtdCompany AS A WITH (NOLOCK)
INNER JOIN LtdCompany AS B WITH (NOLOCK) ON A.LtdCompanyIdentification = B.LtdCompanyIdentification
INNER JOIN LtdComContractor WITH (NOLOCK) ON B.LtdCompanyID = LtdComContractor.LtdCompanyID
INNER JOIN Contract WITH (NOLOCK) ON LtdComContractor.ContractID = Contract.ContractID
AND Contract.ComLocationID IN (2) ) AS LtdCom ON LtdCompany.LtdCompanyID = LtdCom.LtdCompanyID
AND LtdCompany.Name LIKE 'l%'
INNER JOIN LtdComContractor WITH (NOLOCK) ON LtdCompany.LtdCompanyID = LtdComContractor.LtdCompanyID
INNER JOIN (SELECT LtdCompany.LtdCompanyIdentification,
MIN(LtdComContractor.EffectiveDateFrom) AS EffectiveDateFrom FROM LtdCompany WITH (NOLOCK)
INNER JOIN LtdComContractor WITH (NOLOCK) ON LtdCompany.LtdCompanyID = LtdComContractor.LtdCompanyID
GROUP BY LtdCompany.LtdCompanyIdentification HAVING MIN(LtdComContractor.EffectiveDateFrom) > '2005/08/17') AS C
ON C.LtdCompanyIdentification = LtdCompany.LtdCompanyIdentification
AND C.EffectiveDateFrom = LtdComContractor.EffectiveDateFrom
INNER JOIN plcAddress WITH (NOLOCK) ON LtdCom.LtdCompanyID = plcAddress.PlacementID AND plcAddress.AddressType = 4
AND C.EffectiveDateFrom = plcAddress.EffectiveDateFrom
INNER JOIN Address WITH (NOLOCK) ON plcAddress.AddressID = Address.AddressID
UNION SELECT LtdCompany.LtdCompanyID, LtdCompany.Name, LtdCompany.RegNumber, LtdCompany.VATNumber,
LtdCompany.VATEffectiveDate, LtdCompany.BankName, LtdCompany.Branch, LtdCompany.AccountName,
LtdCompany.AccountNumber, LtdCompany.BSRef, LtdCompany.SortCode, LtdCompany.isLtdCompany, Address.Address1,
Address.Address2, Address.Address3, Address.Address4, Address.Address5, Address.PostCode FROM LtdCompany
INNER JOIN (SELECT DISTINCT A.LtdCompanyID FROM LtdCompany AS A WITH (NOLOCK)
INNER JOIN LtdCompany AS B WITH (NOLOCK) ON A.LtdCompanyIdentification = B.LtdCompanyIdentification
INNER JOIN LtdComContractor WITH (NOLOCK) ON B.LtdCompanyID = LtdComContractor.LtdCompanyID
INNER JOIN Contract WITH (NOLOCK) ON LtdComContractor.ContractID = Contract.ContractID
AND Contract.ComLocationID IN (2) ) AS LtdCom ON LtdCompany.LtdCompanyID = LtdCom.LtdCompanyID
AND LtdCompany.Name LIKE 'l%' INNER JOIN LtdComContractor
WITH (NOLOCK) ON LtdCompany.LtdCompanyID = LtdComContractor.LtdCompanyID
INNER JOIN (SELECT LtdCompany.LtdCompanyIdentification, MAX(LtdComContractor.EffectiveDateTo)
AS EffectiveDateTo FROM LtdCompany WITH (NOLOCK)
INNER JOIN LtdComContractor WITH (NOLOCK) ON LtdCompany.LtdCompanyID = LtdComContractor.LtdCompanyID
GROUP BY LtdCompany.LtdCompanyIdentification HAVING MAX(LtdComContractor.EffectiveDateTo) < '2005/08/17') AS C
ON C.LtdCompanyIdentification = LtdCompany.LtdCompanyIdentification
AND C.EffectiveDateTo = LtdComContractor.EffectiveDateTo
INNER JOIN plcAddress WITH (NOLOCK) ON LtdCom.LtdCompanyID = plcAddress.PlacementID AND plcAddress.AddressType = 4
AND ((C.EffectiveDateTo BETWEEN plcAddress.EffectiveDateFrom AND plcAddress.EffectiveDateTo)
OR (C.EffectiveDateTo >= plcAddress.EffectiveDateFrom AND ISDATE(plcAddress.EffectiveDateTo) = 0))
INNER JOIN Address WITH (NOLOCK) ON plcAddress.AddressID = Address.AddressID
ORDER BY LtdCompany.Name"

I noticed am getting locks when this page runs though above reveals WITH (NOLOCK) so don't get that.

The above seems rather complex to me!!! Please feel free to rate the above syntax, the coders of the ASP pages are saying the page in quetion is running slow as the database has grown, yet the largest table here contains 25000 records hardly large!!

Regds

NickyJ
Starting Member

46 Posts

Posted - 2005-08-17 : 10:45:43
Should add that there are 3 UNIONS within and I noticed running them separate returns record counts of say

121 records
0 records
39 records

when run together I get 49 records what would that imply, I also did this whilst removing the DISTINCT and still got 49 records.

Rgds
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2005-08-17 : 11:07:07
A UNION inherently removes any duplicates (you need a UNION ALL to not do that).

The code is dreadful. Its got inherently slow constructions in it, repeated sections that could be moved so they only execute once, dates in non date type fields in a way that prevents use of indexes, aparently completely redudant self-joined tables, nested select statements which are not sufficiently constrained - there are additional constraints outside the nested usage. And the whole use of (NOLOCK) scares the pants of me - plus there are at least 3 places where that hint has been missed off - possible deliberately, hard to say.

What more can I say!

Kristen
Go to Top of Page

AndrewMurphy
Master Smack Fu Yak Hacker

2916 Posts

Posted - 2005-08-17 : 11:26:39
Have a look at the 'estimated execution plan'....have you got indices, statistics, etc on the tables? Giving us the relevant DDL for the tables would help.
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2005-08-17 : 11:36:19
Amazing....

Did you write this?

NOLOCK be berry berry bad for me.....



Brett

8-)

Hint: Want your questions answered fast? Follow the direction in this link
http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspx
Go to Top of Page

NickyJ
Starting Member

46 Posts

Posted - 2005-08-17 : 12:15:28
No not written by me, it's from a Web Application I just put a Trace on and this is the T-SQL, I shall post up the DDL for the tables asap. Any simplification of the above would help, I am slowly breaking it down but I don't venture into SQL too often I'm afraid so please be patient, seeing that though is enough to scare me off forever!
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2005-08-17 : 12:25:39
"Any simplification of the above would help"

Well ... if it was me I wouldn't start from there

I would get a definition of what its supposed to do and rewrite it from scratch (albeit with one eye on the original as a source for Cut&Paste!)

Kristen
Go to Top of Page

NickyJ
Starting Member

46 Posts

Posted - 2005-08-17 : 12:29:23
I thought that would be the answer!! I'll probably do that and compare Execution Plans and returned results, thing is the SQL is passed in Dynamically and I don't have much say in the ASP code, maybe once I have rewritten the SQL I could justify my argument.

Thanks
Nick
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2005-08-17 : 12:39:21
"I thought that would be the answer"

Sorry about that!

"SQL is passed in Dynamically"

Yup, I'd assumed that. Not too much you can do about that, particularly if the actual SQL varies from case-to-case.

Running it via sp_ExecuteSQL, and parameterising it, would help if the same query "style" repeats reasonably frequently - SQL Server will cache a plan for it - and a monster this big might actually be taking a while to build a plan for.

But my Aproach #1 would be to use a Stored Procedure - it might be that using a temporary table to hold some of the recuring data would make the difference between Night and Day - and building temporary tables etc. into a dynamically generated pile of SQL is going to be hard work I would think. So ... if the variability of the SQL itself is not great (hopefully there is none at all, other than the criteria parameters), then an Sproc will have the benefit of better efficiency and performance (plus all the other things that Sprocs score over dynamic SQL - I can list some when that turns out to be the best method and you need to justify it to your colleagues!)

Kristen
Go to Top of Page

NickyJ
Starting Member

46 Posts

Posted - 2005-08-18 : 04:14:01
So a fun day lies ahead of me, and best of all I've a hangover to match!! Thanks for input.
Go to Top of Page
   

- Advertisement -