Slow running query of view - sql
I have a view that summarizes calendar specific data, it is constantly showing performance issues and creating help desk tickets from customers.
We had a DBA on staff for a short time but he never showed up to work so was let go. This has largely been a developer managed database. I have run Brent Ozar's Sps (sp_BlitzFirst) and the queries to this view constantly have the highest cost.
Query Plan: https://www.brentozar.com/pastetheplan/?id=ry8Lo6T74
view code
SELECT
rae.ResourceAvailabilityExceptEventId AS MasterEventEntityId,
me.MasterEventId AS MasterEventId,
null AS ParentEventId,
me.MasterEventBillingInfoId AS MasterEventBillingInfoId,
0 AS HasScheduledParentEvent,
me.Subject AS EventSubject,
me.Description AS EventDescription,
me.EventStartDate AS EventStartDate,
me.EventEndDate AS EventEndDate,
me.TimeZone AS TimeZone,
mebi.TotalBillAmount AS BillAmount,
null AS CancelledReason,
null AS HasDiagnosis,
null AS ParticipantAuthorizationId,
null AS AuthorizationNumber,
null AS AuthorizationDescription,
null AS BillingSourceName,
null AS BillingSourceTypeId,
me.EventTypeId AS EventTypeId,
cet.Description AS EventType,
me.EventSubTypeId AS EventSubTypeId,
cest.Description AS EventSubType,
1 AS IsTimeOff,
0 AS IsInsurance,
CASE WHEN me.MasterEventBillingInfoId is null THEN 0 ELSE 1 END AS IsBillable,
0 AS IsScheduled,
0 AS IsCompleted,
0 AS IsRecurring,
0 AS IsLinkedEvent,
null AS ChildEventTypeId,
null AS ChildEventType,
'timeoff' AS EventStatus,
null AS EventStatusId,
null AS WorkflowStatusId,
null AS WorkflowStatusDescription,
ra.LinkId AS LinkId,
ra.EntityId AS EntityId,
IIF(ra.EntityId = 'E32955F7-1CE8-46A1-98D3-06A69FA4B29E',1,0) AS IsAssignedParticipant,
IIF(ra.EntityId = '173F0473-747A-48F6-B7E8-06948370AAF8',1,0) AS IsAssignedEmployee,
par.PersonId AS ParticipantId,
emp.PersonId AS AssignedEmployeeId,
null AS BillUnderEmployeeId,
null AS SupervisorEmployeeId,
par.FirstName AS ParticipantFirstName,
par.LastName AS ParticipantLastName,
emp.FirstName AS AssignedEmployeeFirstName,
emp.LastName AS AssignedEmployeeLastName,
null AS BillUnderEmployeeFirstName,
null AS BillUnderEmployeeLastName,
null AS SupervisorEmployeeFirstName,
null AS SupervisorEmployeeLastName,
null AS CredentialId,
null AS CredentialName,
me.LocationId AS LocationId,
o.Name AS Location,
0 AS PublishedScoreSheetCount,
0 AS SessionCount,
0 AS AuthItemCount,
null AS BillCodes,
pstat.Description AS PayrollStatus,
me.PayrollStatusId AS PayrollStatusId,
me.PayrollLastExportDate AS PayrollLastExportDate,
me.PayCodeId AS PayCodeId,
pc.Name AS PayCodeName
FROM Data.MasterEvent me
JOIN Data.ResourceAvailabilityExceptEvent rae WITH ( NOLOCK ) ON me.MasterEventId = rae.ResourceAvailabilityExceptEventId
JOIN Data.ResourceAvailability ra WITH ( NOLOCK ) ON rae.ResourceAvailabilityId = ra.ResourceAvailabilityId AND ra.IsSoftDeleted = 0
JOIN Mgr.Code cet WITH ( NOLOCK ) on cet.CodeId = me.EventTypeId
LEFT JOIN Mgr.Code cest WITH ( NOLOCK ) on cest.CodeId = me.EventSubTypeId
LEFT JOIN Data.MasterEventBillingInfo mebi WITH ( NOLOCK ) on me.MasterEventBillingInfoId = mebi.MasterEventBillingInfoId
LEFT JOIN Data.Person emp WITH ( NOLOCK ) on ra.LinkId = emp.PersonId AND ra.EntityId = '173F0473-747A-48F6-B7E8-06948370AAF8'
LEFT JOIN Data.Person par WITH ( NOLOCK ) on ra.LinkId = par.PersonId AND ra.EntityId = 'E32955F7-1CE8-46A1-98D3-06A69FA4B29E'
LEFT JOIN Data.Organization o WITH ( NOLOCK ) ON o.OrganizationId = me.LocationId AND o.IsSoftDeleted = 0
LEFT JOIN Mgr.Code pstat WITH ( NOLOCK ) on pstat.CodeId = me.PayrollStatusId
LEFT JOIN Data.PayCode pc WITH(NOLOCK) on pc.PayCodeId = me.PayCodeId
WHERE me.IsSoftDeleted = 0
UNION
SELECT
mee.MasterEventEntityId,
mee.MasterEventId,
me.ParentEventId,
me.MasterEventBillingInfoId,
CASE WHEN separent.ScheduledEventId is null THEN 0 ELSE 1 END as HasScheduledParentEvent,
me.Subject as EventSubject,
me.Description as EventDescription,
me.EventStartDate,
me.EventEndDate,
me.TimeZone,
mebi.TotalBillAmount AS BillAmount,
COALESCE(se.CancelledReason,sece.CancelledReason,null) AS CancelledReason,
IIF(egb.DiagnosisCodes IS NOT NULL,1,0) AS HasDiagnosis,
mebi.ParticipantAuthorizationId,
auth.AuthorizationNumber,
auth.Description as AuthorizationDescription,
billsrccmp.Name as BillingSourceName,
billsrc.BillingSourceTypeId,
me.EventTypeId,
cet.Description as EventType,
me.EventSubTypeId,
cest.Description as EventSubType,
0 AS IsTimeOff,
CASE
WHEN billsrc.BillingSourceTypeId = 'CCBDBCFC-2225-4511-B617-190430D1897C' THEN 1
else 0 END as IsInsurance,
CASE WHEN me.MasterEventBillingInfoId is null THEN 0 ELSE 1 END as IsBillable,
CASE WHEN se.ScheduledEventId is null THEN 0 ELSE 1 END as IsScheduled,
CASE WHEN ce.CompletedEventId is null THEN 0 ELSE 1 END as IsCompleted,
CASE WHEN se.ScheduleRecurrenceId is null THEN 0 ELSE 1 END as IsRecurring,
IIF(meparent.EventTypeId = '7d881908-d373-43eb-a550-ca5e6b55137c', 0, 1) IsLinkedEvent,
pevstat.EventTypeId as ChildEventTypeId,
pevstat.EventType as ChildEventType,
COALESCE(pevstat.EventStatus, evstat.EventStatus) as EventStatus,
ce.EventStatusId,
ce.WorkflowStatusId,
ceC.Description,
mee.LinkId,
mee.EntityId,
IIF(mee.LinkId = par.ParticipantId, 1, 0) as IsAssignedParticipant,
IIF(mee.LinkId = me.AssignedEmployeeId, 1, 0) as IsAssignedEmployee,
par.ParticipantId,
aemp.EmployeeId as AssignedEmployeeId,
buemp.EmployeeId as BillUnderEmployeeId,
semp.EmployeeId as SupervisorEmployeeId,
pperson.FirstName as ParticipantFirstName,
pperson.LastName as ParticipantLastName,
aeperson.FirstName as AssignedEmployeeFirstName,
aeperson.LastName as AssignedEmployeeLastName,
bueperson.FirstName as BillUnderEmployeeFirstName,
bueperson.LastName as BillUnderEmployeeLastName,
seperson.FirstName as SupervisorEmployeeFirstName,
seperson.LastName as SupervisorEmployeeLastName,
c.CredentialId,
c.Name as CredentialName,
me.LocationId,
o.Name AS Location,
COALESCE(sss.ScheduledScoreSheetCount, css.CompletedScoreSheetCount, 0) as PublishedScoreSheetCount,
COALESCE(sss.ScheduledSessionCount, css.CompletedSessionCount, 0) as SessionCount,
aai.ApptAuthItemCount as AuthItemCount,
bc.BillCodes,
pstat.Description as PayrollStatus,
me.PayrollStatusId,
me.PayrollLastExportDate,
pc.PayCodeId,
pc.Name AS PayCodeName
FROM Data.MasterEventEntity mee WITH ( NOLOCK )
JOIN Data.MasterEvent me WITH ( NOLOCK ) on mee.MasterEventId = me.MasterEventId AND me.IsSoftDeleted = 0
JOIN Views.EventStatus evstat on evstat.MasterEventId = me.MasterEventId
LEFT JOIN Data.Organization o WITH ( NOLOCK ) ON o.OrganizationId = me.LocationId AND o.IsSoftDeleted = 0
LEFT JOIN Views.EventGroupingBase egb on egb.MasterEventId = mee.MasterEventId
LEFT JOIN Data.ScheduledEvent se WITH ( NOLOCK ) on se.ScheduledEventId = me.MasterEventId
LEFT JOIN Data.CompletedEvent ce WITH ( NOLOCK ) on ce.CompletedEventId = me.MasterEventId
LEFT JOIN Mgr.Code ceC WITH ( NOLOCK ) on ce.WorkflowStatusId = ceC.CodeId
LEFT JOIN Data.ScheduledEvent sece WITH ( NOLOCK ) on sece.ScheduledEventId = ce.ScheduledEventId
JOIN Mgr.Code cet WITH ( NOLOCK ) on cet.CodeId = me.EventTypeId
LEFT JOIN Mgr.Code cest WITH ( NOLOCK ) on cest.CodeId = me.EventSubTypeId
LEFT JOIN Data.MasterEvent meparent WITH ( NOLOCK ) on meparent.MasterEventId = me.ParentEventId
LEFT JOIN Data.ScheduledEvent separent WITH ( NOLOCK ) on separent.ScheduledEventId = me.ParentEventId
LEFT JOIN Views.ParentEventStatus pevstat on me.EventTypeId = '7d881908-d373-43eb-a550-ca5e6b55137c' AND pevstat.MasterEventId = me.MasterEventId
LEFT JOIN Data.MasterEventBillingInfo mebi WITH ( NOLOCK ) on mebi.MasterEventBillingInfoId = me.MasterEventBillingInfoId and mebi.IsSoftDeleted = 0
LEFT JOIN Mgr.Code pstat WITH ( NOLOCK ) on pstat.CodeId = me.PayrollStatusId
LEFT JOIN Data.PayCode pc WITH(NOLOCK) on pc.PayCodeId=me.PayCodeId
LEFT JOIN Data.Participant par WITH ( NOLOCK ) on par.ParticipantId = COALESCE(mebi.ParticipantId, mee.LinkId)
LEFT JOIN Data.Person pperson WITH ( NOLOCK ) on pperson.PersonId = par.ParticipantId and pperson.IsSoftDeleted = 0
LEFT JOIN Data.Employee buemp WITH ( NOLOCK ) on buemp.EmployeeId = mebi.BillUnderEmployeeId
LEFT JOIN Data.Person bueperson WITH ( NOLOCK ) on bueperson.PersonId = buemp.EmployeeId and bueperson.IsSoftDeleted = 0
LEFT JOIN Data.Employee aemp WITH ( NOLOCK ) on aemp.EmployeeId = me.AssignedEmployeeId
LEFT JOIN Data.Person aeperson WITH ( NOLOCK ) on aeperson.PersonId = aemp.EmployeeId and aeperson.IsSoftDeleted = 0
LEFT JOIN Data.Credential c WITH ( NOLOCK ) on c.CredentialId = mebi.CredentialId and c.IsSoftDeleted = 0
LEFT JOIN Data.Employee semp WITH ( NOLOCK ) on semp.EmployeeId = mebi.SupervisorEmployeeId
LEFT JOIN Data.Person seperson WITH ( NOLOCK ) on seperson.PersonId = semp.EmployeeId and seperson.IsSoftDeleted = 0
LEFT JOIN Data.ParticipantAuthorization auth WITH ( NOLOCK ) on auth.ParticipantAuthorizationId = mebi.ParticipantAuthorizationId and auth.IsSoftDeleted = 0
LEFT JOIN Data.Contract authContract WITH ( NOLOCK ) on authContract.ContractId = auth.ContractId and authContract.IsSoftDeleted = 0
LEFT JOIN Data.BillingSource billsrc WITH ( NOLOCK ) on billsrc.BillingSourceId = authContract.BillingSourceId
LEFT JOIN Data.Company billsrccmp WITH ( NOLOCK ) on billsrccmp.CompanyId = billsrc.BillingSourceId and billsrccmp.IsSoftDeleted = 0
LEFT JOIN Data.InvoiceCharge ic WITH ( NOLOCK ) on ic.CompletedEventId = me.MasterEventId and ic.InvoiceChargeStatusId != 'A2D34290-8630-4735-ACCF-E08D3D1A9480' and ic.IsSoftDeleted = 0
LEFT JOIN Data.Invoice inv WITH ( NOLOCK ) on ic.InvoiceId = inv.InvoiceId and inv.IsSoftDeleted = 0
LEFT JOIN (SELECT
MasterEventBillingInfoId,
count(AuthorizationItemId) ApptAuthItemCount
FROM Data.MasterEventBillingInfoAuthItem mebiai WITH ( NOLOCK )
WHERE mebiai.IsSoftDeleted = 0
GROUP BY mebiai.MasterEventBillingInfoId) aai ON aai.MasterEventBillingInfoId = mebi.MasterEventBillingInfoId
LEFT JOIN (
SELECT
mbi2.MasterEventBillingInfoId,
STUFF((
SELECT ',' + CONCAT(bc.Name,
IIF(caeai.Modifier1 != '', CONCAT('-', caeai.Modifier1), ''),
IIF(caeai.Modifier2 != '', CONCAT(' ', caeai.Modifier2), ''),
IIF(caeai.Modifier3 != '', CONCAT(' ', caeai.Modifier3), ''),
IIF(caeai.Modifier4 != '', CONCAT(' ', caeai.Modifier4), ''))
FROM Data.MasterEventBillingInfoAuthItem caeai WITH ( NOLOCK )
JOIN Data.AuthorizationItem ai WITH ( NOLOCK ) ON caeai.AuthorizationItemId = ai.AuthorizationItemId AND ai.IsSoftDeleted = 0
JOIN Data.FeeScheduleItem fsi WITH ( NOLOCK ) ON ai.FeeScheduleItemId = fsi.FeeScheduleItemId AND fsi.IsSoftDeleted = 0
JOIN Data.BillCode bc WITH ( NOLOCK ) ON bc.BillCodeId = fsi.BillCodeId AND bc.IsSoftDeleted = 0
WHERE mbi2.MasterEventBillingInfoId = caeai.MasterEventBillingInfoId AND caeai.IsSoftDeleted = 0
ORDER BY bc.Name
FOR XML PATH ('')), 1, 1, '') AS BillCodes
FROM Data.MasterEventBillingInfo mbi2 WITH ( NOLOCK )
) bc ON bc.MasterEventBillingInfoId = mebi.MasterEventBillingInfoId
LEFT JOIN (SELECT
s.ScheduledEventId,
count(s.ScoreSheetId) ScheduledScoreSheetCount,
count(SessionId) ScheduledSessionCount
FROM Data.ScheduledEventScoreSheet s WITH ( NOLOCK )
left join Data.DataSheet ds on s.ScoreSheetId = ds.DataSheetId
WHERE s.IsSoftDeleted = 0 AND ds.DefinitionFinishedDate IS NOT NULL AND ds.CompletionDate IS NULL
GROUP BY s.ScheduledEventId) sss ON sss.ScheduledEventId = me.MasterEventId
LEFT JOIN (SELECT
s.CompletedEventId,
count(ScoreSheetId) CompletedScoreSheetCount,
count(SessionId) CompletedSessionCount
FROM Data.CompletedEventScoreSheet s WITH ( NOLOCK )
WHERE s.IsSoftDeleted = 0
GROUP BY s.CompletedEventId) css ON css.CompletedEventId = me.MasterEventId
WHERE mee.ShowOnCalendar = 1 AND mee.IsSoftDeleted = 0
I need some direction on what I can do, even if it is just recommendations on some good reliable DBA consultants I can bring in.
It might be not the only one big problem, but it looks like you have Key Lookup for 7K values in MasterEventBillingInfoAuthItem table and 300 Lookups in MasterEvent table. Review indexing on these tables.
Related
Where Clause Using Conditional Statement
i have query below SELECT #RoleUser = MR.Code FROM MasterRole MR INNER JOIN MasterUsersRole MUR ON MR.Id = MUR.RoleId INNER JOIN MasterUsers MU ON Mu.UserCode = MUR.UserCode WHERE MU.UserCode = #UserLoginID select 1 Num , MyHistory.ID , MyHistory.RequestNumber , MyHistory.FlowID , MyHistory.FlowProcessStatusID from ( select * from Requests R inner join ( --DECLARE #UserLoginID nvarchar(200) = 'dum.testing.3' select distinct RequestID from dbo.RequestTrackingHistory RTH where IIF(#UserLoginID = 'admin', #UserLoginID, RTH.CreatedBy) = #UserLoginID OR ( CreatedBy IN SELECT Mu.UserCode from MasterUsers MU INNER JOIN MasterUsersRole MUR ON MU.UserCode = MUR.UserCode INNER JOIN MasterRole MR ON MUR.RoleId = MR.Id WHERE MR.Code = #RoleUser ) ) ) RT on R.ID = RT.RequestID ) as MyHistory inner join MasterFlow F on MyHistory.FlowID = F.ID inner join ( select FP.ID , FP.Name , FP.AssignType , FP.AssignTo , FP.IsStart , case FP.AssignType when 'GROUP' then G.Name end as 'AssignToName' from MasterFlowProcess FP left join dbo.MasterRole G on FP.AssignTo = G.ID and FP.AssignType = 'GROUP' ) FP on MyHistory.FlowProcessID = FP.ID inner join MasterFlowProcessStatus FPS on MyHistory.FlowProcessStatusID = FPS.ID left join MasterFlowProcessStatusNext FPSN on FPS.ID = FPSN.ProcessStatusFlowID left join MasterFlowProcess FPN on FPSN.NextProcessFlowID = FPN.ID left JOIN MasterRole MR ON MR.Id = FPN.AssignTo left join MasterUsersRole MUR on MR.Id = MUR.RoleId left join MasterUsers MURO on MUR.UserCode = MURO.UserCode inner join MasterUsers UC on MyHistory.CreatedBy = UC.UserCode left join MasterUsers UU on MyHistory.UpdatedBy = UU.UserCode LEFT JOIN RequestMT RMT ON MyHistory.ID = RMT.RequestID LEFT JOIN RequestGT RGT ON MyHistory.ID = RGT.RequestID left join (SELECT sum(QtyCU) countQty , RequestId from dbo.RequestGTDetail where IsActive = 1 group by RequestId) RGTD on RGTD.RequestId = RGT.RequestId left join (SELECT sum(QtyPCS) countQty , RequestId from dbo.RequestMTDetail where IsActive = 1 group by RequestId) RMTD on RMTD.RequestId = RMT.RequestId left join (SELECT COUNT(IIF(returnable = 0, returnable, null)) countReturnable , RequestId from dbo.RequestMTDetail group by RequestId) RMTR on RMTR.RequestId = RMT.RequestId left JOIN dbo.MasterDistributor md ON md.Code = RGT.CustId or md.Code = RMT.CustId left JOIN dbo.MasterUsersDistributor MUD ON MUD.UserCode = MURO.UserCode AND md.Code = MUD.DistributorCode LEFT JOIN dbo.MasterReason MRMT ON RMT.ReasonId = MRMT.Id LEFT JOIN dbo.MasterReason MRGT ON RGT.ReasonId = MRGT.Id LEFT JOIN dbo.MasterDistributorGroup MDG ON MDG.Id = MD.GroupId OUTER APPLY dbo.FnGetHistoryApproveDate(MyHistory.Id) AS x where REPLACE(FPS.Name, '#Requestor', uc.Name) <> 'DRAFT' AND MUD.DistributorCode IN (SELECT DistributorCode FROM dbo.MasterUsersDistributor WHERE UserCode = #UserLoginID) i want to add some logic in where clause this line ==> AND MUD.DistributorCode IN (SELECT DistributorCode FROM dbo.MasterUsersDistributor WHERE UserCode = #UserLoginID) it depend on the #RoleUser variable, if #RoleUser IN ('A','B') then where clause above is executed, but if #RoleUser Not IN ('A','B') where clause not executed i,m trying this where clause AND IIF(#RoleUser IN ('A','B'), MUD.DistributorCode, #RoleUser) IN (SELECT DistributorCode FROM dbo.MasterUsersDistributor WHERE UserCode = IIF(#RoleUser IN ('A','B'), #UserLoginID, NULL)) it didn't work, only executed if #RoleUser IS ('A','B') other than that it return 0 record any help or advice is really appreciated thank you
The cleanest way I'm implemented these kind of crazy rules is a holderTable and a countVariable against the holder table. I'll give a generic examples. This is a "approach" and "philosophy", not a specific answer....with complex WHERE clauses. DECLARE #customerCountryCount int DECLARE #customerCountry TABLE ( CountryName varchar(15) ) if ( "the moon is blue on tuesday" ) /* << whatever rules you have */ BEGIN INSERT INTO #customerCountry SELECT "Honduras" UNION ALL SELECT "Malaysia" END if ( "favorite color = green" ) /* << whatever rules you have */ BEGIN INSERT INTO #customerCountry SELECT "Greenland" UNION ALL SELECT "Peru" END SELECT #customerCountryCount = COUNT(*) FROM #customerCountry Select * from dbo.Customers c WHERE (#customerCountryCount = 0) OR ( exists (select null from #customerCountry innerVariableTable where UPPER(innerVariableTable.CountryName) = UPPER(c.Country) )) ) This way, instead of putting all the "twisted logic" in an overly complex WHERE statement..... you have "separation of concerns"... Your inserts into #customerCountry are separated from your use of #customerCountry. And you have the #customerCountryCount "trick" to distinguish when nothing was used. You can add a #customerCountryNotExists table as well, and code it to where not exists. As a side note, you may want to try using a #temp table (instead of a #variabletable (#customerCountry above)... and performance test these 2 options. There is no "single answer". You have to "try it out". And many many variables go into #temp table performance (from a sql-server SETUP, not "how you code a stored procedure". That is way outside the scope of this question. Here is a SOF link to "safe" #temp table usage. Temporary table in SQL server causing ' There is already an object named' error
How to add Parameter to report
select distinct sotr_sys_no , SODETS_VINYL_COLOUR , SODETS_MDF_COLOUR , SOTR_PROMISED_DATE , DATEDIFF(dd,getdate(),sotr_promised_date) as DueDays , AEXTRA_5_SHORT_NAME , AEXTRA_5_VINYL_PARTCODE , CASE WHEN SODETS_MDF_COLOUR > '0' THEN AltMDFCode ELSE AEXTRA_5_MDF_PARTCODE END AS AEXTRA_5_MDF_PARTCODE , ISNULL(Vinylqty,0) As VinylQty , ISNULL(MDFqty,0) as MDFQty , Vinyldue , MDFdue , WO.WOOutstanding from Defactouser.F_SO_Transaction WITH (NOLOCK) inner join defactouser.F_SO_Transaction_Details WITH (NOLOCK) on sotr_sys_no = sotd_head_no inner join defactouser.F_SO_Transaction_Details_Extra WITH (NOLOCK) on SOTD_SYS_NO = SODETS_LINK left outer join ( select distinct AEXTRA_5_CODE as AltMDFKey , AEXTRA_5_MDF_PARTCODE AS AltMDFCode from DeFactoUser.F_AD_Extra_5 WITH (NOLOCK) ) as AltMDF on SODETS_MDF_COLOUR = AltMDF.AltMDFKey left outer join defactouser.F_AD_Extra_5 WITH (NOLOCK) on SODETS_VINYL_COLOUR = [AEXTRA_5_CODE] inner join defactouser.F_ST_Products WITH (NOLOCK) on sotd_strc_code = strc_code left Outer join ( SELECT Product_Code As VinylStockCode, sum(Physical_Qty_Units) as Vinylqty FROM DBO.DFBI_Stock_Physical WITH (NOLOCK) WHERE Warehouse = 'DOORS' and LEFT(product_code ,3) = 'vfl' Group By Product_Code HAVING SUM(Physical_Qty_Units) >0 ) VinylStock on AEXTRA_5_VINYL_PARTCODE = VinylStock.VinylStockCode left outer join ( SELECT Product_Code As MDFStockCode, sum(Physical_Qty_Units) as MDFqty FROM DBO.DFBI_Stock_Physical WITH (NOLOCK) WHERE Warehouse = 'PANELS' and LEFT(product_code ,3) = 'MDF' Group By Product_Code HAVING SUM(Physical_Qty_Units) >0 ) MDFStock on CASE WHEN SODETS_MDF_COLOUR > '0' THEN AltMDF.AltMDFCode ELSE AEXTRA_5_MDF_PARTCODE END = MDFStock.MDFStockCode left Outer JOin (select stex_strc_code as VinylStex , sum(STEX_QTY_UNITS) as Qty, MIN(stex_promised_date) as Vinyldue from defactouser.F_ST_Transaction_Expediting where left(stex_strc_code ,3) = 'vfl' and stex_type = 'pop+' group By STEX_STRC_CODE ) VinylStockIn on AEXTRA_5_VINYL_PARTCODE = VinylStex left Outer Join ( select stex_strc_code as MDFStex , sum(STEX_QTY_UNITS) as Qty, MIN(stex_promised_date) as MDFdue from defactouser.F_ST_Transaction_Expediting where left(stex_strc_code ,3) = 'mdf' and stex_type = 'pop+' group By STEX_STRC_CODE ) MDFStockIn on CASE WHEN SODETS_MDF_COLOUR > '0' THEN AltMDF.AltMDFCode ELSE AEXTRA_5_MDF_PARTCODE END = MDFStex LEFT OUTER JOIN ( select SOTD_HEAD_NO, SODETS_VINYL_COLOUR as WOVinyl, SUM(BMTD_QTY_OUTSTANDING) as WOOutstanding from defactouser.f_bm_transactions_details inner join defactouser.F_SO_Transaction_Details on BMTD_ORDER_LINK_NUMBER = SOTD_SYS_NO inner join defactouser.F_SO_Transaction_Details_Extra on BMTD_ORDER_LINK_NUMBER = SODETS_LINK where bmtd_type = 1 and bmtd_bmtr_type = 0 and bmtd_stwh_code in ('doors', 'shef trans') and SOTD_STATUS <99 Group by SOTD_HEAD_NO, SODETS_VINYL_COLOUR ) WO on sotr_sys_no = WO.SOTD_HEAD_NO AND SODETS_VINYL_COLOUR = WO.WOVinyl where (SOTD_QTY_UNITS_OUTSTANDING > 0 and SOTR_TYPE = 10 and SOTD_STWH_CODE IN ('doors' , 'hpp shef') and left(sotd_strc_code ,5) <> 'drill' and SOTR_CUST_CODE <>'hpp' and STRC_ANAL1 = '1027' and ISNULL(VinylQty,0) <10 and DATEDIFF(dd,getdate(),sotr_promised_date) <5 ) or (SOTD_QTY_UNITS_OUTSTANDING > 0 and SOTR_TYPE = 10 and SOTD_STWH_CODE IN ('doors' , 'hpp shef') and left(sotd_strc_code ,5) <> 'drill' and SOTR_CUST_CODE <>'hpp' and STRC_ANAL1 = '1027' and ISNULL(MDFQty,0) <4 and DATEDIFF(dd,getdate(),sotr_promised_date) <5 ) Order By MDFQty, AEXTRA_5_MDF_PARTCODE Currently this query produces a report that returns a table with products due to arrive in the next 5 days. How do I add a parameter to the report that will show me the results as it is, and then also to show a report for products due in whenever. I am using Report Builder 3.0, and have tried to add a parameter but cannot get the desired result. Can this be done without editing the query and just in report builder?
Change you WHERE clause and replace < 5 with < #Days. Assuming the query is not a stored proc and is directly in the dataset query then SSRS will automatically add the #Days parameter to your report.
How to speedup this query?
Do you have some idea of how to speedup this query: SELECT Vosol = ( CASE WHEN EXISTS ( SELECT Id FROM trs.CollectionHeaderView AS chv WHERE chv.ItemNum = itm.ItemNum AND chv.CollectionType = '1' ) THEN ISNULL(itm.Amount, 0) ELSE 0 END ) , Vakhast = ( CASE WHEN EXISTS ( SELECT Id FROM trs.CollectionHeaderView AS chv WHERE chv.ItemNum = itm.ItemNum AND chv.CollectionType = '2' ) THEN ISNULL(itm.Amount, 0) ELSE 0 END ) FROM trs.TrsDocRcvItem AS itm LEFT JOIN trs.TrsDocRcvHeader AS hdr ON itm.HeaderRef = hdr.Id LEFT JOIN acc.DL AS dl ON dl.Id = hdr.DLRef LEFT JOIN trs.TrsDocType AS docType ON docType.Id = hdr.DocTypeRef INNER JOIN sle.SleCustomer AS customer ON customer.DLRef = dl.Id LEFT JOIN trs.AccOperation AS operation ON operation.Id = itm.AccOperationRef WHERE hdr.DocTypeRef NOT IN ( 1141, 1142, 1241, 1242 ) AND ( hdr.State = '1' OR hdr.State = '2' ) AND operation.StateType = '1' I'm trying to optimize sql query which now takes about 6 second to execute. What more can I do to speedup this query? I'm using Microsoft Sql Server.
Use OUTER APPLY to remove the two correlated sub-queries. SELECT Vosol = CASE WHEN chv1 IS NOT NULL THEN Isnull(itm.Amount, 0) ELSE 0 END, Vakhast = CASE WHEN chv2 IS NOT NULL THEN Isnull(itm.Amount, 0) ELSE 0 END FROM trs.TrsDocRcvItem AS itm INNER JOIN trs.TrsDocRcvHeader AS hdr ON itm.HeaderRef = hdr.Id --LEFT JOIN acc.DL AS dl -- ON dl.Id = hdr.DLRef --LEFT JOIN trs.TrsDocType AS docType -- ON docType.Id = hdr.DocTypeRef --INNER JOIN sle.SleCustomer AS customer -- ON customer.DLRef = dl.Id INNER JOIN trs.AccOperation AS operation ON operation.Id = itm.AccOperationRef OUTER apply (SELECT Max(CASE WHEN chv.CollectionType = '1' THEN id END) AS chv1, Max(CASE WHEN chv.CollectionType = '2' THEN id END) AS chv2 FROM trs.CollectionHeaderView AS chv WHERE chv.ItemNum = itm.ItemNum AND chv.CollectionType IN ( '1', '2' )) oa WHERE hdr.DocTypeRef NOT IN ( 1141, 1142, 1241, 1242 ) AND hdr.State IN ( '1', '2' ) AND operation.StateType = '1' I have commented out the acc.DL and sle.SleCustomer tables. I don't see any use of it other than filtering records. If you really need it then uncomment it. Also I have commented the trs.TrsDocType table which again has no use. Unless it has one to many relationship with trs.TrsDocRcvHeader table. If it has one to many relationship then the result simply get duplicated for no reason since you are not selecting anything from trs.TrsDocType table. Still if the query is running slow then you need to create Indexes on the tables involved. Also make sure the statistics are up-to-date After analyzing your execution plan, TrsDocRcvItem table costs 47%. Creating a index on TrsDocRcvItem table should help the query CREATE NONCLUSTERED INDEX NIX_TrsDocRcvItem ON [Trs].[TrsDocRcvItem] (AccOperationRef,ItemNum,HeaderRef) INCLUDE (Amount) Suggested index from the execution plan you have posted CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>] ON [Trs].[TrsDocRcvItem] ([AccOperationRef]) INCLUDE ([ItemNum],[Amount],[HeaderRef])
SELECT Vosol = ( CASE WHEN EXISTS ( SELECT Id FROM trs.CollectionHeaderView AS chv WHERE chv.ItemNum = itm.ItemNum AND chv.CollectionType = '1' ) THEN ISNULL(itm.Amount, 0) ELSE 0 END ) , Vakhast = ( CASE WHEN EXISTS ( SELECT Id FROM trs.CollectionHeaderView AS chv WHERE chv.ItemNum = itm.ItemNum AND chv.CollectionType = '2' ) THEN ISNULL(itm.Amount, 0) ELSE 0 END ) FROM trs.TrsDocRcvItem AS itm INNER JOIN ( SELECT * FROM trs.TrsDocRcvHeader WHERE DocTypeRef NOT IN ( 1141, 1142, 1241, 1242 ) AND ( State = '1' OR State = '2' ) ) hdr ON itm.HeaderRef = hdr.Id LEFT JOIN acc.DL AS dl ON dl.Id = hdr.DLRef LEFT JOIN trs.TrsDocType AS docType ON docType.Id = hdr.DocTypeRef INNER JOIN sle.SleCustomer AS customer ON customer.DLRef = dl.Id INNER JOIN ( SELECT * FROM trs.AccOperation WHERE StateType = '1' ) operation operation.Id = itm.AccOperationRef You can replace WHERE hdr.DocTypeRef NOT IN ( 1141, 1142, 1241, 1242 ) AND ( hdr.State = '1' OR hdr.State = '2' ) AND operation.StateType = '1' To INNER JOIN ( SELECT * FROM trs.TrsDocRcvHeader WHERE DocTypeRef NOT IN ( 1141, 1142, 1241, 1242 ) AND ( State = '1' OR State = '2' ) ) hdr ON itm.HeaderRef = hdr.Id INNER JOIN ( SELECT * FROM trs.AccOperation WHERE StateType = '1' ) operation operation.Id = itm.AccOperationRef I hope that it will help you.
SQL Server - get rid of derived query in join
I'm interested in some suggestions with examples on how to 1)get rid of the derived query in the left outer join and 2)remove/consolidate the cte cteSecType in the code below The derived query in the join chooses the minimum assistant_personnel_number out of a list; there can be multiple primary and backup assistants associated with an employee . thx WITH cteAssistants ( executive_personnel_number, assistant_personnel_number, assistant_type, assign_role ) AS ( SELECT CASE WHEN ISNUMERIC(JP.XA_asgn_emplid) = 1 THEN JP.XA_asgn_emplid ELSE '' END AS executive_personnel_number , JAP.emplid AS assistant_personnel_number , LAT1.FIELDVALUE AS assistant_type , LAT3.xlatshortname AS assign_role FROM dbo.XA_ASGN_PRNT AS KAP LEFT OUTER JOIN dbo.XA_ASSIGNMENTS AS KA ON JP.emplid = JAP.emplid AND JP.effdt = JAP.effdt LEFT OUTER JOIN dbo.XA_EMPLOYEES AS EXECT ON EXECT.EMPLID = JP.XA_ASGN_EMPLID LEFT OUTER JOIN dbo.XA_EMPLOYEES AS ASST ON ASST.EMPLID = JAP.EMPLID LEFT OUTER JOIN dbo.XLATITEM AS XLAT1 ON LAT1.fieldname = 'XA_ASGN_TYPE' AND LAT1.fieldvalue = JAP.XA_asgn_type LEFT OUTER JOIN dbo.XLATITEM AS XLAT3 ON LAT3.fieldname = 'XA_ASGN_ROLE' AND LAT3.fieldvalue = JP.XA_asgn_role WHERE JAP.effdt = ( SELECT MAX(effdt) FROM dbo.XA_ASGN_PRNT WHERE emplid = JAP.emplid AND effdt <= GETDATE() ) --Return data only when both executive and assistant are still active; null is for Floaters AND ( EXECT.HR_STATUS = 'A' OR EXECT.HR_STATUS IS NULL ) AND ASST.HR_STATUS = 'A' AND ( JAP.XA_asgn_type = 'F' OR ( JAP.XA_asgn_type IN ( 'A', 'AF' ) AND JP.XA_asgn_person = 'Y' ) ) ), cteSecType ( assistant_personnel_number, SecType ) AS ( SELECT assistant_personnel_number , assistant_type AS SecType FROM cteAssistants GROUP BY assistant_type , assistant_personnel_number ) SELECT EMP.XA_NETWORK_ID AS network_id , EMP.XA_EMPLID AS empid , EMP.XA_EMPLID AS employeeNumber , EMP.XA_FIRST_NAME AS first_name , EMP.XA_LAST_NAME AS last_name , SECRES.SecType AS SecType , AsstInfo.XA_fml_pref_name AS PrimaryAssistant_FML , AsstInfo.XA_network_id AS PrimaryAssistant_Newtork_ID , AsstInfo.XA_EMPLID AS PrimaryAssistant_EmpID , AsstInfo.XA_phone_ext AS PrimaryAssitant_Extension FROM dbo.XA_EMPLOYEES AS EMP LEFT OUTER JOIN dbo.XA_EMPLOYEES AS MGR ON EMP.supervisor_id = MGR.emplid LEFT OUTER JOIN cteSecType AS SECRES ON CAST(CAST(SECRES.assistant_personnel_number AS INT) AS VARCHAR(11)) = EMP.XA_EMPLID LEFT OUTER JOIN ( SELECT executive_personnel_number AS AttorneyID , MIN(assistant_personnel_number) AS AssistantID FROM cteEmployeeAssistants AS A WHERE ( assign_role = 'Primary' ) GROUP BY executive_personnel_number ) AS ASST ON ASST.AttorneyID = EMP.XA_EMPLID LEFT OUTER JOIN dbo.XA_EMPLOYEES AS ASSTINFO ON ASSTINFO.XA_EMPLID = ASST.AssistantID WHERE ( EMP.HR_STATUS = 'A' ) AND ( EMP.PER_ORG IN ( 'EMP', 'CWR' ) ) AND ( ISNULL(EMP.XA_NETWORK_ID, '') <> '' ) GO
Rewriting Correlated Subquery with "not in" clause
For obvious performance reasons, I would like to rewrite an existing Oracle SQL query that includes correlated subqueries involving "not in" clauses. Can this be accomplished through outer joins or perhaps some other technique? Here is the code: SELECT TRIM(et.event_id), TRIM(et.cancel_evt_id) FROM external_transactions et JOIN transaction_type tt ON et.transaction_type_id = tt.transaction_type_id WHERE et.acct = 'ABCDEF' AND tt.transaction_type_class != 'XYZXYZ' AND ( TRIM(et.event_id) NOT IN ( SELECT TRIM(t1.transaction_evt_id) FROM transactions t1 WHERE t1.acct = et.acct AND t1.asset_id = et.asset_id AND t1.cancel_flag = 'N' ) OR TRIM(et.cancel_evt_id) NOT IN ( SELECT TRIM(t2.cancel_evt_id) FROM transactions t2 WHERE t2.acct = et.acct AND t2.asset_id = et.asset_id AND t2.cancel_flag = 'Y' ) ) ;
Aside from comment, this is assuming your "ID" columns are integer based and not string, don't try to convert them. Also, to help optimize the query, I would ensure you have indexes External_Transactions ( acct, event_id, cancel_evt_id ) Transaction_Type ( transaction_type_id, transaction_type_class ) Transactions ( transaction_evt_id, acct, asset_id, cancel_flag ) Transactions ( cancel_evt_id, acct, asset_id, cancel_flag ) SELECT et.event_id, et.cancel_evt_id FROM external_transactions et JOIN transaction_type tt ON et.transaction_type_id = tt.transaction_type_id AND tt.transaction_type_class != 'XYZXYZ' LEFT OUTER JOIN transactions t1 ON et.event_id = t1.transaction_evt_id AND et.acct = t1.acct AND et.asset_id = t1.asset_id AND t1.cancel_flag = 'N' LEFT OUTER JOIN transactions t2 ON et.cancel_evt_id = t2.cancel_evt_id AND et.acct = t2.acct AND et.asset_id = t2.asset_id AND t2.cancel_flag = 'Y' WHERE et.acct = 'ABCDEF' AND ( t1.transaction_evt_id IS NULL OR t2.cancel_evt_id IS NULL ) You might even benefit slightly if the transaction table had an index on Transactions ( acct, asset_id, cancel_flag, transaction_evt_id, cancel_evt_id ) and the left-join was like SELECT et.event_id, et.cancel_evt_id FROM external_transactions et JOIN transaction_type tt ON et.transaction_type_id = tt.transaction_type_id AND tt.transaction_type_class != 'XYZXYZ' LEFT OUTER JOIN transactions t1 ON et.acct = t1.acct AND et.asset_id = t1.asset_id AND ( ( t1.cancel_flag = 'N' AND et.event_id = t1.transaction_evt_id ) OR ( t1.cancel_flag = 'Y' AND et.cancel_event_id = t1.cancel_evt_id ) ) WHERE et.acct = 'ABCDEF' AND t1.transaction_evt_id IS NULL In both cases, the indexes would be COVERING indexes so it did not have to go back to the raw data pages to confirm other elements of the records
Using NOT EXISTS: SELECT TRIM(et.event_id), TRIM(et.cancel_evt_id) FROM external_transactions et JOIN transaction_type tt ON et.transaction_type_id = tt.transaction_type_id WHERE et.acct = 'ABCDEF' AND tt.transaction_type_class != 'XYZXYZ' AND NOT EXISTS ( SELECT 1 FROM transactions t1 WHERE t1.acct = et.acct AND t1.asset_id = et.asset_id AND ( ( t1.cancel_flag = 'N' AND TRIM(et.event_id) = TRIM(t1.transaction_evt_id) ) OR ( t1.cancel_flag = 'Y' AND TRIM(et.cancel_evt_id) = TRIM(t1.cancel_evt_id) ) ) );