我有这个查询需要2分钟才能执行,即使时间段不长:
SELECT MTI.DeptID,
ShortEmployees.EmpID,
ShortEmployees.EmpName1 AS EmpName,
Sum(CASE
WHEN (BSR.BSTID = 3
AND bli.state IN (12, 13, 14)) THEN -1 * ((BLD.Qty / dbo.Getunitval(BLD.UnitID, BLD.MTID)) * BLD.Price - ((BLD.Qty / dbo.Getunitval(BLD.UnitID, BLD.MTID)) * BLD.Price * BLD.discount * 0.01))
ELSE ((BLD.Qty / dbo.Getunitval(BLD.UnitID, BLD.MTID)) * BLD.Price - ((BLD.Qty / dbo.Getunitval(BLD.UnitID, BLD.MTID)) * BLD.Price * BLD.discount * 0.01))
END) AS Total
FROM BLD
INNER JOIN BLI
ON BLD.BLNo = BLI.BLNo
INNER JOIN BSR
ON BLI.BLID = BSR.BLID
INNER JOIN ShortEmployees
ON BLI.EmpID = ShortEmployees.EmpID
INNER JOIN MTI
ON BLD.MTID = MTI.MTID
WHERE (MTI.DeptID = 'B')
AND (BLI.BLDate > Cast('2013-01-01 00:00:00' AS DATETIME))
AND (BLI.BLDate < Cast('2013-01-14 23:59:59' AS DATETIME))
AND ((BSR.BSTID = 2
AND bli.state IN (2, 6, 8, 9,
10, 12, 18))
OR (BSR.BSTID = 3
AND bli.state IN (12, 13, 14)))
GROUP BY ShortEmployees.EmpName1,
ShortEmployees.EmpID,
MTI.DeptID
ORDER BY Total DESC
我如何优化它?
MTI:项目信息表。
BLI:票据表。
BLD:Bill详细信息表。
ShortEmployees:Salesmen表。
答案 0 :(得分:1)
将条件移动到JOKN ON子句中,可以在进行连接时应用它们,而不是在完成所有连接后进行过滤:
SELECT MTI.DeptID,
ShortEmployees.EmpID,
ShortEmployees.EmpName1 AS EmpName,
Sum(CASE
WHEN (BSR.BSTID = 3
AND bli.state IN (12, 13, 14)) THEN -1 * ((BLD.Qty / dbo.Getunitval(BLD.UnitID, BLD.MTID)) * BLD.Price - ((BLD.Qty / dbo.Getunitval(BLD.UnitID, BLD.MTID)) * BLD.Price * BLD.discount * 0.01))
ELSE ((BLD.Qty / dbo.Getunitval(BLD.UnitID, BLD.MTID)) * BLD.Price - ((BLD.Qty / dbo.Getunitval(BLD.UnitID, BLD.MTID)) * BLD.Price * BLD.discount * 0.01))
END) AS Total
FROM BLD
JOIN BLI ON BLD.BLNo = BLI.BLNo
AND BLI.BLDate BETWEEN Cast('2013-01-01 00:00:00' AS DATETIME)
AND Cast('2013-01-14 23:59:59' AS DATETIME)
JOIN BSR ON BLI.BLID = BSR.BLID
AND ((BSR.BSTID = 2
AND bli.state IN (2, 6, 8, 9, 10, 12, 18)
OR (BSR.BSTID = 3
AND bli.state IN (12, 13, 14))
JOIN ShortEmployees ON BLI.EmpID = ShortEmployees.EmpID
JOIN MTI ON BLD.MTID = MTI.MTID
AND MTI.DeptID = 'B'
GROUP BY ShortEmployees.EmpName1,
ShortEmployees.EmpID,
MTI.DeptID
ORDER BY Total DESC
请注意,我将日期范围检查更改为BETWEEN,因为您的查询排除了该期间的第一个和最后一个秒。
我还删除了不必要的括号和缩进
答案 1 :(得分:0)
最后,我最终将该查询转换为整个存储过程,差异很大!现在它只需要2秒:),谢谢大家特别讨厌的喋喋不休;)
答案 2 :(得分:0)
要进行其他优化,请在变量中移动Cast('XXXXX'AS DATETIME):
DECLARE @dmin DATETIME= Cast('2013-01-01 00:00:00' AS DATETIME);
DECLARE @dmax DATETIME= Cast('2013-01-14 23:59:59' AS DATETIME);
SELECT [blah]
FROM [blahblah]
WHERE (MTI.DeptID = 'B')
AND (BLI.BLDate BETWEEN @dmin AND @dmax)
etc