您对如何加快此查询有所了解:
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'
我正在尝试优化sql查询,现在需要大约6秒才能执行。 我还能做些什么来加速这个查询? 我正在使用Microsoft Sql Server。
答案 0 :(得分:2)
使用OUTER APPLY
删除两个相关的子查询。
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'
我已对acc.DL
和sle.SleCustomer
表进行了注释。除了过滤记录之外,我没有看到它的任何用途。如果你真的需要它,那么取消注释它。
此外,我评论了trs.TrsDocType
表再次没用。除非它与trs.TrsDocRcvHeader
表有一对多的关系。如果它具有一对多的关系,那么结果就会无缘无故地重复,因为您没有从trs.TrsDocType
表中选择任何内容。
如果查询运行缓慢,则需要在所涉及的表上创建Indexes
。另外,请确保statistics
是最新的
在分析执行计划后,TrsDocRcvItem
表费用47%
。在TrsDocRcvItem
表上创建索引应该有助于查询
CREATE NONCLUSTERED INDEX NIX_TrsDocRcvItem
ON [Trs].[TrsDocRcvItem] (AccOperationRef,ItemNum,HeaderRef)
INCLUDE (Amount)
您已发布的执行计划的建议索引
CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [Trs].[TrsDocRcvItem] ([AccOperationRef])
INCLUDE ([ItemNum],[Amount],[HeaderRef])
答案 1 :(得分:1)
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
您可以替换
WHERE hdr.DocTypeRef NOT IN ( 1141, 1142, 1241, 1242 )
AND ( hdr.State = '1'
OR hdr.State = '2'
)
AND operation.StateType = '1'
要
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
我希望它会对你有所帮助。