我有两个查询都给出相同的结果,但一个比另一个更快
查询一
SELECT
MP.MilestonePlanningID, SUM(TS.UnitsUsed) TotalUnits
FROM
MilestonePlanning MP
INNER JOIN
Timesheet TS ON MP.MilestonePlanningID = TS.MilestonePlanningID
INNER JOIN
PlanningAction PA ON MP.LastPlanningActionID = PA.ActionID
WHERE
PA.ActionNameID = 4
AND PA.ActionDateTime >= DATEADD(MONTH,-1,GETDATE())
GROUP BY
MP.MilestonePlanningID
查询二
SELECT MP.MilestonePlanningID, SUM(TS.UnitsUsed) TotalUnits
FROM MilestonePlanning MP
INNER JOIN Timesheet TS ON MP.MilestonePlanningID = TS.MilestonePlanningID
INNER JOIN PlanningAction PA ON MP.LastPlanningActionID = PA.ActionID
WHERE PA.ActionNameID = 4
AND CAST(PA.ActionDateTime AS TIMESTAMP) >= CAST(DATEADD(MONTH,-1,GETDATE()) AS TIMESTAMP)
GROUP BY MP.MilestonePlanningID
查询一是最容易使用的查询,也是我开始的查询,但执行需要大约 9 - 15 秒,但是当我删除以下内容时,它仍然是即时的
AND PA.ActionDateTime >= DATEADD(MONTH,-1,GETDATE())
查询二是即时的,有或没有以下行
AND CAST(PA.ActionDateTime AS TIMESTAMP) >= CAST(DATEADD(MONTH,-1,GETDATE()) AS TIMESTAMP)
查询二也不是查看从上个月到今天的数据的最明显的方式。谁能向我解释一下这里发生了什么,以及我在查询一中做错了什么
最佳答案
对于此查询:
SELECT MP.MilestonePlanningID, SUM(TS.UnitsUsed) TotalUnits
FROM MilestonePlanning MP INNER JOIN
Timesheet TS
ON MP.MilestonePlanningID = TS.MilestonePlanningID INNER JOIN
PlanningAction PA
ON MP.LastPlanningActionID = PA.ActionID
WHERE PA.ActionNameID = 4 AND PA.ActionDateTime >= DATEADD(MONTH,-1,GETDATE())
GROUP BY MP.MilestonePlanningID;
我建议在 PlanningAction(ActionNameId, ActionDateTime, ActionId)
、MilestonePlanning(LastPlanningActionID, MilestonePlanningID)
和 Timesheet(MilestonePlanningID)
上建立索引。
最好的猜测(没有执行计划)是 SQL Server 在第一个查询中选择了错误的索引。 Timestamp
并不是真正应该转换到的东西。它用于行版本控制。毫无疑问,这会阻止在 ActionDateTime
上使用索引,而这可能有助于查询。
关于sql - SUM 和带有日期的Where 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32501862/