SQl query optimzation - sql

*can anyone help me optimizing the query. I am using this query in an ETL called streamsets and it is yielding 70 records for 6 minutes when i run an streamsets pipleline which is very slow.we are taking this query from an SSIS package and joining each of the tables using left outer joins.I need to optimize it so that it fetches atleast 1000 records per minute in streamsets *
SELECT [FR].[ORDER_ID]
, [FR].[FULFILLMENT_REQUEST_ID]
, [SR].[SCREENING_RESULT_ID]
, [AT].[AG_TASK_ID]
, [RCC].[RESULT_CRIM_CASE_ID]
, [RCC].[RESULT_CRIM_CHARGE_ID]
, [FR].[JURISDICTION_ID]
, [COUNTY] = CASE WHEN [FR].[PRODUCT_ID] = 2 THEN [JC].[COUNTY_NAME] ELSE '' END
, [STATE] = CASE WHEN [FR].[PRODUCT_ID] = 2 THEN [JC].[STATE_A2_CD] ELSE [JS].[STATE_A2_CD] END
, [JT].[JURISDICTION_TYPE_NAME]
, [FR].[PRODUCT_ID]
, [P].[PRODUCT_NAME]
, [FR].[ORGANIZATION_ID]
, [O].[ORGANIZATION_NAME]
, [SA].[SALARY_RANGE]
, [AGE] = YEAR(GETDATE()) - YEAR([FR].[SUBJECT_DOB])
, [FR].[SUBJECT_JOB_COUNTRY]
, [FR].[SUBJECT_JOB_STATE]
, [FR].[ENTRY_DATE]
, [FR].[CREATION_DATE]
, [FR].[CLOSED_DATE]
, [FR].[EXTERNAL_USER_ID]
, [FR].[GENDER_CODE_ID]
, [GC].[GENDER_CODE_VALUE]
, [AT].[DATA_SOURCE]
, [SU].[RESEARCHER_CLASS]
, [TT].[TASK_TYPE]
, [TT].[TASK_DESCRIPTION]
, [RCC].[CHARGE_DESCRIPTION]
, [RCC].[DISPOSITION_DESCRIPTION]
, [P].[GENERAL_LEDGER_NBR]
, [O].[SCHEME_AGENCY_ID]
, [RT].[RESULT_TYPE_ID]
, [RT].[RESULT_CATEGORY]
, [RT].[RESULT_TYPE]
, [SU].[USER_ID]
,FR.AG_STATUS_ID
, [SCREENING_REFERENCE_ID]=CAST(LEFT([FR].[SCREENING_REFERENCE_ID],250) AS VARCHAR(8000))
,[P1].POD_NAME
, ATH.AG_TASK_HISTORY_ID
,ATH.TASK_STATUS TASK_HISTORY_STATUS
, ATH.AG_TASK_DATE TASK_HISTORY_DATE
,[TT].[TASK_TYPE_ID]
,ATH.MODIFIED_BY_SYSTEM_USER_ID
,ATH.CF_SYSTEM_USER_ID
,'' AS [STATUS NOTES]
, FR.SCOPE_OF_SEARCH
, SR.COMMONNAMFLAG
,CASE WHEN SU.RESEARCHER_CLASS = 'EXTERNAL' THEN SU.[USER_ID] END AS VENDOR
, CASE [TT].TASK_TYPE_ID WHEN 14 THEN 'SD IN' WHEN 15 THEN 'MR' WHEN 1 THEN 'ER' END AS [REQUIRED_ACTION]
, CASE
WHEN [TT].TASK_TYPE_ID = 1 THEN
CASE ATH.TASK_STATUS
WHEN 'DOCUMENTUPLOADED' THEN 'FMT RECORD ENTRY'
WHEN 'ACKNOWLEDGED' THEN 'SEARCHES'
WHEN 'AWAITINGHITENTRY' THEN 'AWAITING HIT'
WHEN 'DISPUTE' THEN 'AWAITING HIT'
WHEN 'DOUBLEENTERRESULTS' THEN 'AWAITING HIT'
WHEN 'NEW' THEN 'SEARCHES'
WHEN 'SOURCEUNAVAILABLE' THEN 'SEARCHES'
WHEN 'UPLOADED' THEN 'SEARCHES'
END
WHEN [TT].TASK_TYPE_ID = 15 THEN
CASE ATH.TASK_STATUS
WHEN 'DISPUTE' THEN 'QC'
WHEN 'DOCUMENTUPLOADED' THEN 'QC'
WHEN 'DOUBLESMARTDATAREVIEW' THEN 'QC'
WHEN 'MANUALREVIEW' THEN 'QC'
END
WHEN [TT].TASK_TYPE_ID = 14 THEN
CASE ATH.TASK_STATUS
WHEN 'DISPUTE' THEN 'QC'
WHEN 'INFONEEDED' THEN 'QC'
WHEN 'INFOPROVIDED' THEN 'QC'
WHEN 'INFONEEDEDACK' THEN 'QC'
WHEN 'NEW' THEN 'QC'
WHEN 'SDINFONEEDED' THEN 'CD COMPLIANCE'
END
END AS [AOM STATUS]
, CASE
WHEN [TT].TASK_TYPE_ID = 1 AND
ATH.TASK_STATUS = 'DOCUMENTUPLOADED' AND
ATH.MODIFIED_BY_SYSTEM_USER_ID IS NOT NULL AND
ATH.CF_SYSTEM_USER_ID IS NOT NULL THEN 'ER DOCUMENT UPLOADED COMPLETE'
WHEN [TT].TASK_TYPE_ID = 14 AND
ATH.TASK_STATUS = 'INFONEEDED' THEN 'SD INFO NEEDED INFO NEEDED DATA'
WHEN [TT].TASK_TYPE_ID = 1 AND SU.RESEARCHER_CLASS = 'INTERNAL' AND
FR.AG_STATUS_ID NOT IN (152) THEN 'ER INTERNAL'
WHEN [TT].TASK_TYPE_ID = 1 AND
ATH.TASK_STATUS = 'AWAITINGHITENTRY' AND
ATH.MODIFIED_BY_SYSTEM_USER_ID IS NOT NULL AND
ATH.CF_SYSTEM_USER_ID IS NOT NULL AND
ATH.MODIFIED_BY_SYSTEM_USER_ID = ATH.CF_SYSTEM_USER_ID THEN 'ER AWAITING HIT ENTRY DATA'
WHEN [TT].TASK_TYPE_ID = 14 THEN 'SD INFO NEEDED DATA'
WHEN [TT].TASK_TYPE_ID = 15 AND
ATH.TASK_STATUS = 'INFONEEDED' THEN 'MR INFO NEEDED'
END AS AG_OPS_STATUS
, FR.EXTERNAL_ORDER_ID
, AOT.OTD
, drv_pod_name=[P1].POD_NAME
, TAT_IN_MIN= Case when TAT_IN_MIN < 0 then 0 else TAT_IN_MIN end
, SU2.USER_ID CF_SYS_USER
, SU3.USER_ID MODIFIED_SYS_USER
, GETDATE() GET_DATE
FROM AG_TASK_HISTORY [ATH] LEFT OUTER JOIN
(
(
(
(
(
(
(
(
(
SELECT [ORDER_ID] ,[FULFILLMENT_REQUEST_ID],[JURISDICTION_ID],[PRODUCT_ID],[ORGANIZATION_ID],[SUBJECT_DOB],[SUBJECT_JOB_COUNTRY],[SUBJECT_JOB_STATE],[ENTRY_DATE],[CREATION_DATE],[CLOSED_DATE],[EXTERNAL_USER_ID],[GENDER_CODE_ID],AG_STATUS_ID,[SCREENING_REFERENCE_ID],SCOPE_OF_SEARCH,EXTERNAL_ORDER_ID,POD_ID,[SALARY_RANGE_ID],[JURISDICTION_TYPE]
FROM [FULFILLMENT_REQUEST]
) FR
LEFT JOIN
(
(SELECT [SCREENING_RESULT_ID],[RESULT_TYPE_ID],[FULFILLMENT_REQUEST_ID],COMMONNAMFLAG FROM [SCREENING_RESULT] )[SR]
INNER JOIN [DBO].[RESULT_TYPE] [RT]
ON [RT].[RESULT_TYPE_ID] = [SR].[RESULT_TYPE_ID]
)
ON [SR].[FULFILLMENT_REQUEST_ID] = [FR].[FULFILLMENT_REQUEST_ID]
)
INNER JOIN [PRODUCT] [P]
ON [P].[PRODUCT_ID] = [FR].[PRODUCT_ID]
INNER JOIN [ORGANIZATION] [O]
ON [O].[ORGANIZATION_ID] = [FR].[ORGANIZATION_ID]
LEFT JOIN(
(SELECT [AG_TASK_ID],[DATA_SOURCE],[TASK_TYPE_ID],[FULFILLMENT_REQUEST_ID],[SYSTEM_USER_ID] FROM [AG_TASK] ) [AT]
INNER JOIN [TASK_TYPE] [TT]
ON [TT].[TASK_TYPE_ID] = [AT].[TASK_TYPE_ID]
)
ON [AT].[FULFILLMENT_REQUEST_ID] = [FR].[FULFILLMENT_REQUEST_ID])
LEFT OUTER JOIN (
(SELECT [RESULT_CRIM_CASE_ID],[SCREENING_RESULT_ID] FROM [RESULT_CRIM_CASE])[RC]
INNER JOIN (SELECT [RESULT_CRIM_CASE_ID],[RESULT_CRIM_CHARGE_ID],[CHARGE_DESCRIPTION],[DISPOSITION_DESCRIPTION] FROM [RESULT_CRIM_CHARGE]) [RCC]
ON [RCC].[RESULT_CRIM_CASE_ID] = [RC].[RESULT_CRIM_CASE_ID]
)
ON [SR].[SCREENING_RESULT_ID] = [RC].[SCREENING_RESULT_ID]
)
)
LEFT JOIN [SYSUSER] [SU]
ON [SU].[SYSTEM_USER_ID] = [AT].[SYSTEM_USER_ID]
LEFT OUTER JOIN [SALARY_RANGE] [SA]
ON [SA].[SALARY_RANGE_ID] = [FR].[SALARY_RANGE_ID]
)
LEFT OUTER JOIN [JURISDICTION_TYPE] [JT]
ON [JT].[JURISDICTION_TYPE_ID] = [FR].[JURISDICTION_TYPE]
)
LEFT OUTER JOIN [GENDER_CODE] [GC]
ON [GC].[GENDER_CODE] = [FR].[GENDER_CODE_ID]
)
LEFT OUTER JOIN [JURISDICTION_COUNTY] [JC]
ON [JC].[JURISDICTION_ID] = [FR].[JURISDICTION_ID]
LEFT OUTER JOIN [JURISDICTION_STATE] [JS]
ON [JS].[JURISDICTION_ID] = [FR].[JURISDICTION_ID]
)
ON [ATH].AG_TASK_ID=[AT].AG_TASK_ID
LEFT OUTER JOIN [POD] [P1] ON [FR].POD_ID = [P1].POD_ID
LEFT OUTER JOIN(
SELECT *, (DATEDIFF(MINUTE, [IN_DATE], [IP_DATE]))-(DATEDIFF(WK, [IN_DATE], [IP_DATE]) * (2*24*60))-
(CASE WHEN DATENAME(DW, [IN_DATE]) = 'SUNDAY'
THEN (24*60) ELSE 0 END)
-(CASE WHEN DATENAME(DW, [IP_DATE]) = 'SATURDAY'
THEN (24*60) ELSE 0 END) TAT_IN_MIN
FROM (
SELECT FULFILLMENT_REQUEST_ID , MAX([IN_DATE]) [IN_DATE], MAX([IP_DATE]) [IP_DATE]
FROM(
SELECT AG_TASK_HISTORY.FULFILLMENT_REQUEST_ID,
CASE WHEN (AG_TASK_HISTORY.TASK_STATUS='INFONEEDED' OR AG_TASK_HISTORY.TASK_STATUS='NEW') AND (SYSUSER.RESEARCHER_CLASS='EXTERNAL' OR SU1.RESEARCHER_CLASS ='EXTERNAL')
THEN AG_TASK_HISTORY.AG_TASK_DATE END [IN_DATE],
CASE WHEN (AG_TASK_HISTORY.TASK_STATUS='INFOPROVIDED' OR AG_TASK_HISTORY.TASK_STATUS='COMPLETE' OR AG_TASK_HISTORY.TASK_STATUS='DOCUMENTUPLOADED') AND (SYSUSER.RESEARCHER_CLASS='EXTERNAL' OR SU1.RESEARCHER_CLASS ='EXTERNAL')
THEN AG_TASK_HISTORY.AG_TASK_DATE END AS [IP_DATE]
FROM AG_TASK_HISTORY
LEFT JOIN SYSUSER(NOLOCK) ON AG_TASK_HISTORY.CF_SYSTEM_USER_ID = SYSUSER.SYSTEM_USER_ID
LEFT JOIN SYSUSER(NOLOCK) SU1 ON AG_TASK_HISTORY.MODIFIED_BY_SYSTEM_USER_ID = SU1.SYSTEM_USER_ID
WHERE AG_TASK_DATE >=CAST('01-JAN-'+CAST(YEAR(GETDATE())-3 AS CHAR(4))AS DATETIME)
) A GROUP BY FULFILLMENT_REQUEST_ID
)B
)AVT
ON FR.FULFILLMENT_REQUEST_ID = AVT.FULFILLMENT_REQUEST_ID
LEFT OUTER JOIN(
SELECT *, (DATEDIFF(DAY, [IN_DATE], [IP_DATE]))-
(DATEDIFF(WK, [IN_DATE], [IP_DATE]) * (2))-
(CASE WHEN DATENAME(DW, [IN_DATE]) = 'SUNDAY' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(DW, [IP_DATE]) = 'SATURDAY' THEN 1 ELSE 0 END) OTD
FROM
(
SELECT FULFILLMENT_REQUEST_ID , MIN(CREATION_DATE) [IN_DATE], GETDATE() [IP_DATE]
FROM FULFILLMENT_REQUEST WHERE CLOSED_DATE IS NULL AND AG_STATUS_ID NOT IN (29,134,142,152)
GROUP BY FULFILLMENT_REQUEST_ID
)B
) AOT
ON FR.FULFILLMENT_REQUEST_ID = AOT.FULFILLMENT_REQUEST_ID
LEFT OUTER JOIN SYSUSER SU2
ON ATH.CF_SYSTEM_USER_ID=SU2.SYSTEM_USER_ID
LEFT OUTER JOIN SYSUSER SU3
ON ATH.MODIFIED_BY_SYSTEM_USER_ID=SU3.SYSTEM_USER_ID
WHERE SU.RESEARCHER_CLASS='EXTERNAL' AND (AVT.TAT_IN_MIN >0 OR AOT.[IP_DATE] IS NULL)
AND ATH.AG_Task_Date >=' 2017-07-07 09:02:23.050'

If you join tables and subselects you really have to know your indexes.
Use explain to check if there is a problem with using indexes.
It is possible that the query can't be optimized and has to be completely redesigned.

It's very hard to give you definite answer to your question because your query is huge and it will take long time to analyze it.
Here are some suggestions to you:
Get execution plan for it (copy it to SMSS and hit CTRL+L) that might give you suggestions what indexes are missing
Remove all the columns from the select list and leave just SELECT COUNT(*) FROM AG_TASK_HISTORY .... Check if you still have bad performance.
Then go from the bottom and eliminate join by join. After each elimination see if the performance is still bad.
After some eliminations you'll must probably get good time and that's means that you've found at least 1 bottleneck.
Then create a proper index for that and try again from step 2.
Other considerations would be to use stored procedures (if it possible) and split this big query into smaller parts, but I am pretty sure that with proper set of the indexes you can get much better performance than you have now.

Related

Use CTE in SQL to flag DUPLICATES and reference in sub-query

So I have the following CTE:
with dupeinv AS (
select * from (
select
tci.t_idoc,
tci.t_idat,
ROW_NUMBER() OVER (partition by tci.t_idoc ORDER BY tci.t_idoc, tci.t_idat DESC) as rn
from [ln106].[dbo].tcisli305100 tci
) as t
where t.rn = 1
)
There are duplicates in the above table ([ln106].[dbo].tcisli305100) , hence the CTE to get single values. I want to format just these values in the below query (prefixed with ---)
select 'JCI' as BU,
RTRIM(LTRIM(cl.t_orno)) AS SALES_ORDER_NUMBER
, cl.t_pono AS SALES_ORDER_LINE_NUMBER
, CONCAT(cl.t_shpm, cl.t_pono, cl.t_idoc) AS SHIPPING_RECORD_ID
,CASE WHEN cl.t_dqua = 0 or cl.t_dqua is null THEN cl.t_amti ELSE
cl.t_amti / cl.t_dqua END AS AR_INVOICE_LINE_ITEM_PRICE_LOCAL
, cl.t_line AS AR_INVOICE_LINE_NUMBER
, cl.t_dqua AS AR_INVOICE_LINE_ITEM_QUANTITY
--- , concat(dupeinv.t_idoc,'|',format(dupeinv.t_idat,'MMddyyyy') ---
,ci.t_ccur AS AR_INVOICE_CURRENCY
, ci.t_idat AS AR_INVOICE_DATE
FROM [ln106].[dbo].tcisli310100 cl
LEFT JOIN [ln106].[dbo].tcisli305100 ci ON cl.t_idoc = ci.t_idoc
LEFT JOIN t di on cl.t_doc = di_t_doc
LEFT JOIN (SELECT t_orno,t_pono FROM [ln106].[dbo].ttdsls401100 WHERE t_oltp <> 1 group by t_orno,t_pono) as l --Jed 10162020 Changed the join to prevent duplicate records
ON l.t_orno=cl.t_orno COLLATE SQL_Latin1_General_CP1_CI_AS AND l.t_pono=cl.t_pono
LEFT JOIN dupeinv tci on cl.r_idoc = ci.t_doc
WHERE ci.t_idat > '2017'
Query doesn't like me referencing it in the main query. Can anyone help, or suggest a better idea?
Your final query should look something like this:
WITH dupeinv AS
(SELECT *
FROM
(SELECT tci.t_idoc,
tci.t_idat,
ROW_NUMBER() OVER (PARTITION BY tci.t_idoc
ORDER BY tci.t_idoc,
tci.t_idat DESC) AS rn
FROM [ln106].[dbo].tcisli305100 tci) AS t
WHERE t.rn = 1 )
SELECT 'JCI' AS BU,
RTRIM(LTRIM(cl.t_orno)) AS SALES_ORDER_NUMBER ,
cl.t_pono AS SALES_ORDER_LINE_NUMBER ,
CONCAT(cl.t_shpm, cl.t_pono, cl.t_idoc) AS SHIPPING_RECORD_ID ,
CASE
WHEN cl.t_dqua = 0
OR cl.t_dqua IS NULL THEN cl.t_amti
ELSE cl.t_amti / cl.t_dqua
END AS AR_INVOICE_LINE_ITEM_PRICE_LOCAL ,
cl.t_line AS AR_INVOICE_LINE_NUMBER ,
cl.t_dqua AS AR_INVOICE_LINE_ITEM_QUANTITY ,
concat(dupeinv.t_idoc,
'|',
format(dupeinv.t_idat, 'MMddyyyy')) ,
ci.t_ccur AS AR_INVOICE_CURRENCY ,
ci.t_idat AS AR_INVOICE_DATE
FROM [ln106].[dbo].tcisli310100 cl
LEFT JOIN [ln106].[dbo].tcisli305100 ci ON cl.t_idoc = ci.t_idoc
LEFT JOIN t di ON cl.t_doc = di_t_doc
LEFT JOIN
(SELECT t_orno,
t_pono
FROM [ln106].[dbo].ttdsls401100
WHERE t_oltp <> 1
GROUP BY t_orno,
t_pono) AS l --Jed 10162020 Changed the join to prevent duplicate records
ON l.t_orno=cl.t_orno COLLATE SQL_Latin1_General_CP1_CI_AS
AND l.t_pono=cl.t_pono
LEFT JOIN dupeinv tci ON cl.r_idoc = ci.t_doc
WHERE ci.t_idat > '2017'

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.

Oracle Join - Which is faster - using the whole table or a subquery that has specific columns needed in the table?

I am really new into optimizing queries. Could you please advise which INNER JOIN runs faster?
Please note that i am using two different ways of inner join syntax(have same # of records)
1.) INNER JOIN of subqueries that have DISTINCT and selected columns only from its respective table
select
fac.fac_id ,
dept.dept_id ,
wk.week_id ,
sum(case when TRIM(fpl.MEASURE) like '%Salar%Wage%' then DATAVALUE else 0 end) WAGES_AMT,
sum(case when TRIM(fpl.MEASURE) like '%Tot%Man%hour%Ret%' then DATAVALUE else 0 end) MANHRS_QTY,
fpl.md_cycle_nbr ,
fpl.md_load_dt
from
EAS_STG.FPA_PLAN_LABOR fpl
INNER JOIN
(
select distinct(dept_nbr), dept_id
from department_D
where regexp_instr( Dept_nbr,'([^0-9])') = 0
) dept
ON TO_NUMBER(TRIM( 'D' FROM fpl.department)) = TO_NUMBER(dept.dept_nbr)
INNER JOIN
(
select distinct(FAC.FAC_NBR), fai.fac_id
from FACILITY_D fac, FACILITY_ALTERNATE_ID fai
where fac.fac_id = fai.fac_id
and fac.company_id = 1101
) fac
ON TRIM(REPLACE(fpl.facility, 'Fac-')) = fac.fac_nbr
INNER JOIN
(
select distinct(wk_hierarchy_id) week_id from DAY_HIERARCHY_D
) wk ON TO_NUMBER(TRIM(REPLACE(fpl.scenario, 'Plan ')) || TRIM(REPLACE(fpl.time, 'Wk '))) = WK.week_id
GROUP BY
fac.fac_id ,
dept.dept_id ,
wk.week_id ,
fpl.md_cycle_nbr ,
fpl.md_load_dt
;
2.) INNER JOIN of the whole table without the selected columns
SELECT fac.fac_id
, dept.dept_id
, d.wk_hierarchy_id week_id
, SUM(CASE WHEN TRIM(fpl.MEASURE) LIKE '%Salar%Wage%' THEN datavalue ELSE 0 END) WAGES_AMT
, SUM(CASE WHEN TRIM(fpl.MEASURE) LIKE '%Tot%Man%hour%Ret%' THEN datavalue ELSE 0 END) MANHRS_QTY
, fpl.md_cycle_nbr
, fpl.md_load_dt
FROM EAS_STG.FPA_PLAN_LABOR fpl
JOIN department_d dept
ON TO_NUMBER(TRIM( 'D' FROM fpl.department)) = TO_NUMBER(dept.dept_nbr)
JOIN facility_d fac
ON TRIM(REPLACE(fpl.facility, 'Fac-')) = fac.fac_nbr
JOIN facility_alternate_id fai
ON fac.fac_id = fai.fac_id
JOIN day_hierarchy_d d
ON TO_NUMBER(TRIM(REPLACE(fpl.scenario, 'Plan ')) || TRIM(REPLACE(fpl.time, 'Wk '))) = d.wk_hierarchy_id
WHERE fac.company_id = 1101
AND REGEXP_INSTR(dept_nbr,'([^0-9])') = 0
GROUP BY fac.fac_id
, dept.dept_id
, d.wk_hierarchy_id
, fpl.md_cycle_nbr
, fpl.md_load_dt
;

sql sum() causing doubling of values with left outer join

The left out join on dbo.SalespersonProject is causing the value for TranAmt to double. I need to sum the legit TranAmt for projects, but adding in the left outer join and SalesPerson02, causes a match an incorrect doubling.
SELECT ARDoc.SlsperId AR_Doc_Sls_ID
, CASE
WHEN ARTran.TranType = 'CM' THEN SUM(ARTran.TranAmt) * -1
ELSE SUM(ARTran.TranAmt)
END TranAmt
, MAX(CASE
WHEN SalesCommOrder = 1 THEN SalesPersonId
END) Salesperson01
, MAX(ISNULL(CASE
WHEN SalesCommOrder = 1 THEN Percentage
END, .03)) Commission01
, MAX(CASE
WHEN SalesCommOrder = 2 THEN SalesPersonId
END) Salesperson02
, MAX(CASE
WHEN SalesCommOrder = 2 THEN Percentage
END) Commission02
, PJPROJ.project PJ_ID
, PJPROJ.project_desc PJ_Description
, PJPROJ.slsperid SME
, ARDoc.CustId Cust_ID
, CASE
WHEN RTRIM(ARTran.InvtId) = 'GRAPHICS' THEN 1
WHEN RTRIM(ARTran.InvtID) = 'SERVICE CONTRACT' THEN 2
END InvtID
, RTRIM(ARDoc.CustId) + ' ' + Customer.BillName Cust_ID_Name
, CONVERT( DATE, ARTran.TranDate, 101) Doc_Date
, ARTran.TranType Doc_Type
, ARTran.RefNbr
, PJPROJ.start_date
, SUM(ARTran.ExtCost) ExtCost
, SUM(ARTran.UnitPrice) UnitPrice
, SUM(ARTran.Qty) Qty
, (
SELECT SUM(b.eac_amount) [Budg Rev]
FROM pjptdsum b
INNER JOIN pjacct a ON a.acct = b.acct
AND a.acct_type = 'RV'
WHERE ARDoc.ProjectID = b.project) Budget_Rev
, (
SELECT SUM(b.eac_amount) [Budg Rev]
FROM pjptdsum b
INNER JOIN pjacct a ON a.acct = b.acct
AND a.acct_type = 'EX'
WHERE ARDoc.ProjectID = b.project) Budget_EAC
, so.TotMerch SalesOrderTotal
, Salesperson.Name
, ARTran.PerPost
, PJPROJ.manager2
, PJEMPLOY.emp_name
FROM Testnewgroundapp.dbo.ARDoc ARDoc
INNER JOIN Testnewgroundapp.dbo.ARTran ARTran ON ARDoc.CustId = ARTran.CustId
AND ARDoc.RefNbr = ARTran.RefNbr
AND ARDoc.DocType = ARTran.TranType
INNER JOIN Testnewgroundapp.dbo.Customer Customer ON ARDoc.CustId = Customer.CustId --INNER JOIN #CustomerTab ct
LEFT OUTER JOIN Testnewgroundapp.dbo.Salesperson Salesperson ON ARDoc.SlsperId = Salesperson.SlsperId
LEFT OUTER JOIN Testnewgroundapp.dbo.PJPROJ PJPROJ ON ARDoc.ProjectID = PJPROJ.project
LEFT OUTER JOIN Testnewgroundapp.dbo.PJEMPLOY PJEMPLOY ON PJPROJ.manager2 = PJEMPLOY.employee
LEFT OUTER JOIN (
SELECT h.PerPost
, h.SlsperID
, SUM(h.TotMerch) TotMerch
FROM SOShipHeader H
GROUP BY h.PerPost
, h.SlsperID) so ON ARTran.PerPost = so.PerPost
AND ARDoc.SlsperId = so.SlsperID
LEFT OUTER JOIN TestCommissions.dbo.SalespersonProject SalespersonProject ON SalespersonProject.ProjectId = PJPROJ.project --AND SalespersonProject.SalesPerson_Id = #ApplicationUserID
LEFT OUTER JOIN TestCommissions.dbo.SalesPerson AppSalesPerson ON AppSalesPerson.Id = SalespersonProject.SalesPerson_Id
WHERE
(ARTran.TranType = 'CM'
AND ARTran.DrCr = 'D'
OR ARTran.DrCr = 'C'
AND
(ARTran.TranType = 'CS'
OR ARTran.TranType = 'DM'
OR ARTran.TranType = 'IN'
)
)
AND ARTran.TaskID NOT LIKE '%60850'
AND ARTRan.TaskID NOT LIKE '%60900'
AND ARTran.invtid <> 'TSCINC001'
AND ARTran.TranClass NOT IN ('F', 'N', 'T')
AND ARTran.Acct NOT IN ('2590', '2040', '2037')
AND CONVERT(INT, ARTran.Acct) > 1301
AND CONVERT(INT, ARTran.PerPost) BETWEEN 201504 AND 201504
AND ARTran.Rlsed = 1
AND PJPROJ.project IS NOT NULL
AND artran.cpnyid IN ('R', 'A')
GROUP BY ARDoc.SlsperId
, ARDoc.ProjectID
, PJPROJ.project
, PJPROJ.project_desc
, PJPROJ.slsperid
, ARDoc.CustId
, ARTran.InvtId
, Customer.BillName
, ARTran.TranDate
, ARTran.TranType
, ARTran.RefNbr
, PJPROJ.start_date
, so.TotMerch
, Salesperson.Name
, ARTran.PerPost
, ARDoc.CpnyID
, PJPROJ.manager2
, PJEMPLOY.emp_name
HAVING ARDoc.SlsperId = 'bpettit'
ORDER BY ARDoc.SlsperId, ARTran.PerPost, PJPROJ.project
If an extra joined table has two records per one main record, this makes each main record appear twice in the result set. The following grouping and summing will then sum each value of the main record or another joined table twice.
Temporarily remove the grouping and summing, but keep all the joins and look at the result set. You will then probably see what causes this doubling.