如何优化此SQL查询?

时间:2009-05-06 04:50:42

标签: sql sql-server-2005 tsql

现在我有这个SQL查询,它有效但总是超时:

SELECT 
(
SELECT (MAX(WP_ODOMETER) - MIN(WP_ODOMETER)) / DATEDIFF(DAY, MIN(WP_DATETIME), MAX(WP_DATETIME))
FROM WAYPOINTS
WHERE WP_DATETIME BETWEEN DATEADD(DAY,-14,GETDATE()) AND GETDATE()
AND WP_VTDID = 'L088'
)
AS MAXD, 
(
SELECT MAX(WP_ODOMETER) 
FROM WAYPOINTS
WHERE WP_DATETIME BETWEEN DATEADD(DAY,-14,GETDATE()) AND GETDATE()
AND WP_VTDID = 'L088'
)
AS MD

我想基于上面的SQL查询创建一个视图。像这样:

SELECT L_VTDID
(
SELECT (MAX(WP_ODOMETER) - MIN(WP_ODOMETER)) / DATEDIFF(DAY, MIN(WP_DATETIME), MAX(WP_DATETIME))
FROM WAYPOINTS
WHERE WP_DATETIME BETWEEN DATEADD(DAY,-14,GETDATE()) AND GETDATE()
AND WP_VTDID = LOCOMOTIVES.L_VTDID
)
AS MAXD, 
(
SELECT MAX(WP_ODOMETER) 
FROM WAYPOINTS
WHERE WP_DATETIME BETWEEN DATEADD(DAY,-14,GETDATE()) AND GETDATE()
AND WP_VTDID = LOCOMOTIVES.L_VTDID
)
AS MD
FROM LOCOMOTIVES

3 个答案:

答案 0 :(得分:3)

信不信由你,客户端语言实际上非常能够进行减法和除法等等。所以,由我来决定,我会简化查询(特别是因为这个版本给出了麻烦):

SELECT MAX(WP_ODOMETER) AS MAX_ODO,
       MIN(WP_ODOMETER) AS MIN_ODO, 
       MIN(WP_DATETIME) AS MIN_DATE,
       MAX(WP_DATETIME) AS MAX_DARE
  FROM WAYPOINTS
 WHERE WP_DATETIME BETWEEN DATEADD(DAY,-14,GETDATE()) AND GETDATE()
   AND WP_VTDID = 'L088'

如果在客户端处理日期计算存在严重问题,那么我承认您可能需要在服务器上生成MAX_DATE和MIN_DATE之间的差异,但是获得一个主机语言可能会更好允许你进行日期计算。

答案 1 :(得分:1)

由于它们具有相同的where子句,您可以将它们组合起来:

SELECT 
MAX(WP_ODOMETER),
(MAX(WP_ODOMETER) - MIN(WP_ODOMETER)) / 
DATEDIFF(DAY, MIN(WP_DATETIME), MAX(WP_DATETIME))
FROM WAYPOINTS
WHERE WP_DATETIME BETWEEN DATEADD(DAY,-14,GETDATE()) AND GETDATE()
AND WP_VTDID = 'L088'

WP_VTDID的索引,WP_DATETIME可以加快速度。您还可以在索引中包含WP_ODOMETER,以将书签查找从索引保存到表本身。

如果由于其他人正在锁定表而发生超时,请尝试将from语句更改为:

FROM WAYPOINTS (NOLOCK)

如果查询在NOLOCK中运行正常,则另一个进程正在使用该表并阻止您的查询锁定行。

答案 2 :(得分:0)

WAYPOINTS是否在WP_DATETIME和WP_VTDID索引?

相关问题