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) )
)
);