我有一个大查询,返回大约10,000行,执行大约需要15-20秒。这是一个遗留查询,我们希望提高性能。我们使用4-5内部连接和子查询。
我在执行计划中看到子查询/或条件正在创建惰性线轴,我想删除它。
您能否告诉我如何删除额外条件并提高查询性能。
SELECT
mc.OTCCustomerID,
'L' + CONVERT(VARCHAR, MC.custlevel) AS Custlevel,
@CustomerNbr,
@ParentNumber,
OTC1.ParentNumber AS GParent,
OINV.DisputeCnt,
OINV.Matter,
OINV.MatterDesc,
OINV.MatterTrust,
OINV.TransactionNbr,
OINV.TransactionDt,
OINV.TransactionDueDt,
OINV.NextActionDt,
OINV.InvoiceStatusId,
OINV.RemainingBalance,
OINV.TransactionCurrencyCd,
OINV.RemainingTransactionBalance,
OINV.Days,
OINV.BillingTmkNm,
OINV.SupervisingTmk,
OINV.ClientPartnerNm,
LEFT(MC.customernm,20) AS CustomerNm,
OINV.IsTransactionReopen,
OINV.IsBPTPCode,
CD.PrimaryDecodeTxt AS outcome,
OINV.TransactionType,
OINV.CollectorComments,
ISNULL(OINV.OTCInvoiceDetailsID,0) AS OTCInvoiceDetailsID,
OINV.BalanceDue,
OINV.Amount,
OINV.CheckNbr,
OINV.ExpectedDepositDt
FROM dbo.OTCCustomer MC WITH( NOLOCK)
JOIN dbo.OTCInvoiceDetails OINV WITH( NOLOCK)
ON MC.OTCCUSTOMERID = OINV.OTCCUSTOMERID
JOIN dbo.CODEDETAIL CD WITH( NOLOCK)
ON OINV.CollectionEffortOutComeID= CD.ID
JOIN dbo.PrioritizationTypeFilter PTF WITH( NOLOCK)
ON OINV.TransactionType = PTF.FilterName
JOIN OTCCollectionStrategyFilter CSF WITH( NOLOCK)
ON PTF.PrioritizationFilterID = CSF.PrioritizationFilterID
AND CSF.CollectionStrategyId = @strategyID
JOIN dbo.OTCCustomer OTC1
ON MC.ParentNumber = OTC1.CustomerNbr
AND OINV.InvoiceStatusId = 5
AND OINV.CSExecSource IS NOT NULL
AND (((SELECT DATEDIFF(dd,GETDATE(),OINV.NextActionDt)) <= 0)
OR
((OINV.CollectionEffortOutComeID IN (
SELECT id
FROM dbo.codedetail WITH( NOLOCK)
WHERE IsPTPEnabled = 1))
AND (SELECT DATEDIFF(dd,GETDATE(),OINV.ExpectedDepositDt)) <= 0)
OR
(OINV.CollectionEffortOutComeID IN (
SELECT id
FROM dbo.codedetail WITH( NOLOCK)
WHERE IsBPTPEnabled = 1)))
AND
OINV.CollectionEffortOutComeID NOT IN (
SELECT id
FROM dbo.codedetail WITH( NOLOCK)
WHERE PrimaryDecodeTxt = 'DL01-Dunning Letter 1'
OR PrimaryDecodeTxt = 'DL02-Dunning Letter 2'
OR PrimaryDecodeTxt = 'DL03-Dunning Letter 3')
答案 0 :(得分:0)
您可以简化的一件事是您不要将DATEDIFF语句写为“SELECT ....”,您可以这么说:
AND DATEDIFF(dd, GETDATE(), OINV.NextActionDt) <= 0
甚至更简单:
AND OINV.NextActionDt < GETDATE()
其次,根据CodeDetail表的大小,您可能希望在执行其他操作之前查询它。类似的东西:
;
WITH CodeDetailFoo AS (
SELECT id, IsPTPEnabled, IsBPTPEnabled
FROM dbo.codedetail WITH ( NOLOCK )
WHERE IsPTPEnabled = 1 OR IsBPTPEnabled = 1
)
<<PUT THE REST OF YOUR QUERY HERE and use CodeDetailFoo>>
“WITH”方法意味着表格会在前面而不是每行进行查询。
答案 1 :(得分:0)
我认为这应该更快,我没有办法检查语法,请检查
SELECT *
FROM
(
SELECT
mc.OTCCustomerID,
'L' + CONVERT(VARCHAR, MC.custlevel) AS Custlevel,
@CustomerNbr,
@ParentNumber,
OTC1.ParentNumber AS GParent,
OINV.DisputeCnt,
OINV.Matter,
OINV.MatterDesc,
OINV.MatterTrust,
OINV.TransactionNbr,
OINV.TransactionDt,
OINV.TransactionDueDt,
OINV.NextActionDt,
OINV.InvoiceStatusId,
OINV.RemainingBalance,
OINV.TransactionCurrencyCd,
OINV.RemainingTransactionBalance,
OINV.Days,
OINV.BillingTmkNm,
OINV.SupervisingTmk,
OINV.ClientPartnerNm,
LEFT(MC.customernm,20) AS CustomerNm,
OINV.IsTransactionReopen,
OINV.IsBPTPCode,
CD.PrimaryDecodeTxt AS outcome,
OINV.TransactionType,
OINV.CollectorComments,
ISNULL(OINV.OTCInvoiceDetailsID,0) AS OTCInvoiceDetailsID,
OINV.BalanceDue,
OINV.Amount,
OINV.CheckNbr,
OINV.ExpectedDepositDt,
CASE WHEN DATEDIFF(dd,GETDATE(),OINV.NextActionDt) <= 0 THEN 1
WHEN (UDF_TBL.MY_IND = 2 AND OINV.CollectionEffortOutComeID = UDF_TBL.ID AND DATEDIFF(dd,GETDATE(),OINV.ExpectedDepositDt) <= 0) THEN 1
WHEN (UDF_TBL.MY_IND = 1 AND OINV.CollectionEffortOutComeID = UDF_TBL.ID) THEN 1
ELSE 0 END AS FILTER_IND
FROM dbo.OTCCustomer MC WITH( NOLOCK)
JOIN dbo.OTCInvoiceDetails OINV WITH( NOLOCK)
ON MC.OTCCUSTOMERID = OINV.OTCCUSTOMERID
JOIN dbo.CODEDETAIL CD WITH( NOLOCK)
ON OINV.CollectionEffortOutComeID= CD.ID
JOIN dbo.PrioritizationTypeFilter PTF WITH( NOLOCK)
ON OINV.TransactionType = PTF.FilterName
JOIN OTCCollectionStrategyFilter CSF WITH( NOLOCK)
ON PTF.PrioritizationFilterID = CSF.PrioritizationFilterID
AND CSF.CollectionStrategyId = @strategyID
JOIN dbo.OTCCustomer OTC1
ON MC.ParentNumber = OTC1.CustomerNbr
AND OINV.InvoiceStatusId = 5
AND OINV.CSExecSource IS NOT NULL
AND OINV.CollectionEffortOutComeID NOT IN (
SELECT id
FROM dbo.codedetail WITH( NOLOCK)
WHERE PrimaryDecodeTxt = 'DL01-Dunning Letter 1'
OR PrimaryDecodeTxt = 'DL02-Dunning Letter 2'
OR PrimaryDecodeTxt = 'DL03-Dunning Letter 3')
LEFT JOIN
(
SELECT id, CASE WHEN IsBPTPEnabled = 1 THEN 1 WHEN IsPTPEnabled = 1 THEN 2 END AS MY_IND
FROM dbo.codedetail WITH( NOLOCK)
WHERE IsPTPEnabled = 1 OR IsBPTPEnabled = 1
) AS UDF_TBL
ON OINV.CollectionEffortOutComeID = UDF_TBL.ID
) A
WHERE FILTER_IND = 1