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.
| Author |
Topic |
|
TheFuzz4
Starting Member
6 Posts |
Posted - 2009-07-07 : 12:55:24
|
| Hey Everyone,This is my first post on here I have this query that is currently running and it takes it anywhere from 45 seconds to a full min to return back just 252 rows. A lot of this has to do with the calculations that are taking place in the query and also in the WHERE clause as well. I am not the original author of this query it was given to me to optimize but I'm running out of ideas here on how to optimize this monster. I have gone through and added in some joins to kill off some of the sub queries but in doing so it actually caused it to run even longer. This query is actually used in a view if it needs to be converted over to a stored procedure to filter it down at the start that is fine but I'd rather keep it as a view so I don't have to go back into the code for the application and change everything out to work as procedure instead of a view. Thank you in advance for your help with this.SELECT DISTINCT a.DisbursementID, a.DisbursementAuthorizationID, h.ServiceType, CAST( ( SELECT SUM( AmountApplied ) FROM dtDisbursementDetails WHERE DisbursementID = a.DisbursementID ) AS MONEY ) AS DisbursementAmount, ( SELECT TOP 1 CustomInteger FROM dtEvents WHERE EventTypeID = 23 AND CaseID IN ( SELECT CaseID FROM dtEvents WHERE EventID = e.EventID ) ORDER BY EventDate DESC ) AS AssignPCID, ( SELECT TOP 1 LastName + ', ' + FirstName FROM dtPerson WHERE PersonID = e.PayerPersonID ) AS ClientName, ( SELECT CASE h.ServiceTypeID WHEN 6 THEN (SELECT TOP 1 ISNULL(LastName + ', ','') + ISNULL(FirstName, '') FROM dtPerson WHERE PersonID = (SELECT TOP 1 BilledBy FROM dtReceivables WHERE ReceivableID = e.ReceivableID)) ELSE (SELECT TOP 1 Organization FROM dtOrganizations WHERE OrganizationID = (SELECT TOP 1 ConsumerOrganizationID FROM dtReceivables WHERE ReceivableID = e.ReceivableID )) END) AS Victim, CAST( (( SELECT SUM( ISNULL(AmountApplied,0) ) FROM dtPaymentDetails WHERE PaymentDetailID IN ( SELECT PaymentDetailID FROM dtDisbursementDetails WHERE DisbursementID = a.DisbursementID )) - (SELECT ISNULL(SUM(AmountApplied),0) FROM cu_sacs_dtCheckDetails WHERE CheckID IN (SELECT CheckID FROM cu_sacs_dtCheck WHERE VoidDate IS NULL) AND CheckID IN (SELECT CheckID FROM cu_sacs_dtCheckDetails WHERE DisbursementDetailID IN (SELECT DisbursementDetailID FROM dtDisbursementDetails WHERE DisbursementID = a.DisbursementID)))) AS MONEY) AS RemainingAmount, a.GroupCheck, h.ServiceTypeID, ( SELECT CASE h.ServiceTypeID WHEN 6 THEN (SELECT TOP 1 PersonID FROM dtPerson WHERE PersonID = (SELECT TOP 1 BilledBy FROM dtReceivables WHERE ReceivableID = e.ReceivableID)) ELSE (SELECT TOP 1 OrganizationID FROM dtOrganizations WHERE OrganizationID = (SELECT TOP 1 ConsumerOrganizationID FROM dtReceivables WHERE ReceivableID = e.ReceivableID )) END) AS VictimID, a.GroupCheckByID, e.ProviderOrganizationID, (SELECT OrganizationID FROM ulSecUser WHERE PersonID = AuthorizedByID) AS AuthorizingOrganization, (SELECT ISNULL(LastName + ', ', '') + ISNULL(FirstName,'') FROM dtPerson WHERE PersonID = AuthorizedByID) AS AuthorizedBy FROM cu_sacs_dtDisbursementAuthorization a JOIN dtDisbursements b ON a.DisbursementID = b.DisbursementID JOIN dtDisbursementDetails c ON b.DisbursementID = c.DisbursementID JOIN dtPaymentDetails d ON c.PaymentDetailID = d.PaymentDetailID JOIN dtReceivables e ON d.ReceivableID = e.ReceivableID JOIN dtOrganizationServiceFees f ON e.FeeID = f.OrganizationServiceFeeID JOIN dtOrganizationServices g ON f.OrganizationServiceID = g.OrganizationServiceID JOIN ulServiceTypes h ON g.ServiceTypeID = h.ServiceTypeID WHERE a.Authorized = 1 AND a.AuthorizedDate IS NOT NULL AND a.PrintedDate IS NULL AND ISNULL(( SELECT SUM( AmountApplied ) FROM dtPaymentDetails WHERE PaymentDetailID IN ( SELECT PaymentDetailID FROM dtDisbursementDetails WHERE DisbursementID = a.DisbursementID )), 0 ) - ISNULL(( SELECT SUM( AmountApplied ) FROM cu_sacs_dtCheckDetails WHERE CheckID IN ( SELECT CheckID FROM cu_sacs_dtCheck WHERE VoidDate IS NULL ) AND CheckID IN ( SELECT CheckID FROM cu_sacs_dtCheckDetails WHERE DisbursementDetailID IN ( SELECT DisbursementDetailID FROM dtDisbursementDetails WHERE DisbursementID = a.DisbursementID))), 0 ) > 0JasonHandel IT |
|
|
GilaMonster
Master Smack Fu Yak Hacker
4507 Posts |
Posted - 2009-07-07 : 13:23:22
|
| I'd start by trying to move those correlated subqueries down into the from clause (as either subqueries or just joined in tables). Same with the subqueries in the where clause.--Gail ShawSQL Server MVP |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2009-07-07 : 13:43:38
|
And make use of the new windowed function to take care of the MAX and SUM within a group. N 56°04'39.26"E 12°55'05.63" |
 |
|
|
TheFuzz4
Starting Member
6 Posts |
Posted - 2009-07-07 : 13:59:21
|
| Could you explain to me the use of the windowed function? This is something new that I have not heard of yet. Thanks.JasonHandel IT |
 |
|
|
TheFuzz4
Starting Member
6 Posts |
Posted - 2009-07-07 : 14:07:47
|
| I think I have found a nice explanation of this from this site.[url]http://articles.techrepublic.com.com/5100-10878_11-6168402.html#[/url] for using the window functions.JasonHandel IT |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2009-07-07 : 14:10:14
|
This is a start, but I leaning on giving up because of the utter mess. I am about halfway done.There are no table aliases in front of columns names and so on...SELECT a.DisbursementID, a.DisbursementAuthorizationID, h.ServiceType, SUM(c.AmountApplied) OVER (PARTITION BY a.DisbursementID) AS DisbursementAmount,( SELECT TOP 1 CustomInteger FROM dtEvents WHERE EventTypeID = 23 AND CaseID IN ( SELECT CaseID FROM dtEvents WHERE EventID = e.EventID ) ORDER BY EventDate DESC ) AS AssignPCID,( SELECT TOP 1 LastName + ', ' + FirstName FROM dtPerson WHERE PersonID = e.PayerPersonID ) AS ClientName, CASE h.ServiceTypeID WHEN 6 THEN (SELECT TOP 1 ISNULL(LastName + ', ','') + ISNULL(FirstName, '') FROM dtPerson WHERE PersonID = (SELECT TOP 1 BilledBy FROM dtReceivables WHERE ReceivableID = e.ReceivableID)) ELSE (SELECT TOP 1 Organization FROM dtOrganizations WHERE OrganizationID = (SELECT TOP 1 ConsumerOrganizationID FROM dtReceivables WHERE ReceivableID = e.ReceivableID )) END AS Victim, SUM(COALESCE(d.AmountApplied, 0)) OVER (PARTITION BY d.PaymentDetailID) - SUM(AmountApplied),0) FROM cu_sacs_dtCheckDetails WHERE CheckID IN (SELECT CheckID FROM cu_sacs_dtCheck WHERE VoidDate IS NULL) AND CheckID IN (SELECT CheckID FROM cu_sacs_dtCheckDetails WHERE DisbursementDetailID IN (SELECT DisbursementDetailID FROM dtDisbursementDetails WHERE DisbursementID = a.DisbursementID)))) AS MONEY) AS RemainingAmount, a.GroupCheck, h.ServiceTypeID,( SELECT CASE h.ServiceTypeID WHEN 6 THEN (SELECT TOP 1 PersonID FROM dtPerson WHERE PersonID = (SELECT TOP 1 BilledBy FROM dtReceivables WHERE ReceivableID = e.ReceivableID))ELSE (SELECT TOP 1 OrganizationID FROM dtOrganizations WHERE OrganizationID = (SELECT TOP 1 ConsumerOrganizationID FROM dtReceivables WHERE ReceivableID = e.ReceivableID )) END) AS VictimID, a.GroupCheckByID, e.ProviderOrganizationID, xx.OrganizationID AS AuthorizingOrganization,(SELECT ISNULL(LastName + ', ', '') + ISNULL(FirstName,'') FROM dtPerson WHERE PersonID = AuthorizedByID) AS AuthorizedByFROM cu_sacs_dtDisbursementAuthorization AS aINNER JOIN dtDisbursements AS b ON b.DisbursementID = a.DisbursementIDINNER JOIN dtDisbursementDetails AS c ON c.DisbursementID = b.DisbursementIDINNER JOIN dtPaymentDetails AS d ON d.PaymentDetailID = c.PaymentDetailIDINNER JOIN dtReceivables AS e ON e.ReceivableID = d.ReceivableIDINNER JOIN dtOrganizationServiceFees AS f ON f.OrganizationServiceFeeID = e.FeeIDINNER JOIN dtOrganizationServices AS g ON g.OrganizationServiceID = f.OrganizationServiceIDINNER JOIN ulServiceTypes AS h ON h.ServiceTypeID = g.ServiceTypeIDLEFT JOIN ulSecUser AS xx ON xx.PersonID = {}.AuthorizedByIDWHERE a.Authorized = 1 AND a.AuthorizedDate IS NOT NULL AND a.PrintedDate IS NULLAND ISNULL(( SELECT SUM( AmountApplied ) FROM dtPaymentDetails WHERE PaymentDetailID IN ( SELECT PaymentDetailID FROM dtDisbursementDetails WHERE DisbursementID = a.DisbursementID )), 0 )- ISNULL(( SELECT SUM( AmountApplied ) FROM cu_sacs_dtCheckDetails WHERE CheckID IN ( SELECT CheckID FROM cu_sacs_dtCheck WHERE VoidDate IS NULL ) AND CheckID IN ( SELECT CheckID FROM cu_sacs_dtCheckDetails WHERE DisbursementDetailID IN ( SELECT DisbursementDetailID FROM dtDisbursementDetails WHERE DisbursementID = a.DisbursementID))), 0 )> 0 N 56°04'39.26"E 12°55'05.63" |
 |
|
|
TheFuzz4
Starting Member
6 Posts |
Posted - 2009-07-07 : 14:37:46
|
| Thank you all for all of your help with this. I am now starting to make some progress on this I think.JasonHandel IT |
 |
|
|
TheFuzz4
Starting Member
6 Posts |
Posted - 2009-07-07 : 15:21:26
|
| Does anyone have any ideas on how to optimize this section of the where clause? I tried to use the windowing functions in there only to find out that I can't put window functions in a where clause. I also can't put in direct aggregate functions either unless they are contained in a sub query that is not related to the main query directly. Thanks AND ISNULL(( SELECT SUM( AmountApplied ) FROM dtPaymentDetails WHERE PaymentDetailID IN ( SELECT PaymentDetailID FROM dtDisbursementDetails WHERE DisbursementID = a.DisbursementID )), 0 ) - ISNULL(( SELECT SUM( AmountApplied ) FROM cu_sacs_dtCheckDetails WHERE CheckID IN ( SELECT CheckID FROM cu_sacs_dtCheck WHERE VoidDate IS NULL ) AND CheckID IN ( SELECT CheckID FROM cu_sacs_dtCheckDetails WHERE DisbursementDetailID IN ( SELECT DisbursementDetailID FROM dtDisbursementDetails WHERE DisbursementID = a.DisbursementID))), 0 ) > 0JasonHandel IT |
 |
|
|
|
|
|
|
|