替换 sql 服务器子查询以使查询更快而不是爬行
Replace sql server subquery to make query faster instead of crawling
我想加快这个查询的速度,我正在尝试各种连接,但我似乎无法结束对带有连接的 storm2 = 1 和 storm2 = 2 的重复查询
SELECT v1.id
,v1.StormOut
,v1.StormNo
,v1.StormYes
,v1.Equipment
,(
SELECT TimeOn
FROM [v_StormLog]
WHERE vehicle = v1.Vehicle
AND Storm2 = 1
AND CurrentDate = v1.CurrentDate
) AS TimeOn
,v1.Vehicle
,v1.NAME
,v1.Equipment AS Equip
,(
SELECT ScheduleOrig
FROM [v_StormLog]
WHERE vehicle = v1.Vehicle
AND Storm2 = 1
AND CurrentDate = v1.CurrentDate
) AS ScheduleOrig
,(
SELECT ScheduleHTML
FROM [v_StormLog]
WHERE vehicle = v1.Vehicle
AND Storm2 = 1
AND CurrentDate = v1.CurrentDate
) AS ScheduleHTML
,(
SELECT Schedule
FROM [v_StormLog]
WHERE vehicle = v1.Vehicle
AND Storm2 = 1
AND CurrentDate = v1.CurrentDate
) AS Schedule
,(
SELECT TimeOff
FROM [v_StormLog]
WHERE vehicle = v1.Vehicle
AND Storm2 = 1
AND CurrentDate = v1.CurrentDate
) AS TimeOff
,v1.StormTimeOn
,v1.StormTimeOff
,v1.StormOut AS 'Out'
,v1.StormYes AS Yes
,v1.StormNo AS No
,(
SELECT comments
FROM [v_StormLog]
WHERE vehicle = v1.Vehicle
AND Storm2 = 1
AND CurrentDate = v1.CurrentDate
) AS comments
,v1.StormComments
,(
SELECT Comments
FROM [v_StormLog]
WHERE vehicle = v1.Vehicle
AND Storm2 = 1
AND CurrentDate = v1.CurrentDate
) AS CommentsHTML
,v1.Storm2
FROM [v_StormLog] v1
WHERE DATEADD(dd, DATEDIFF(dd, 0, v1.[CurrentDate]), 0) = @Date
AND v1.sgroup = 'North'
AND v1.Storm2 = @storm2
ORDER BY v1.ScheduleHTML
,v1.NAME
您需要加入 table 本身。这将减少内部select的数量。您仍然应该检查执行计划是否有正确的索引
SELECT v1.*, v2.* -- update using the fields you need
FROM [v_StormLog] v1
JOIN [v_StormLog] v2
ON v2.vehicle = v1.Vehicle
AND v2.CurrentDate = v1.CurrentDate
WHERE
DATEADD(dd, DATEDIFF(dd, 0, v1.[CurrentDate]), 0) = @Date
AND v1.sgroup = 'North'
AND v1.Storm2 = @storm2
AND v2.Storm2 = 1
您还有重复的字段
,v1.StormOut
,v1.StormNo
,v1.StormYes
和
,v1.StormOut AS 'Out'
,v1.StormYes AS Yes
,v1.StormNo AS No
如果我没记错的话,那种子查询样式会转换为 OUTER JOIN,但是您应该检查您的执行计划以确定。假设是这样:
SELECT v1.id
,v1.StormOut
,v1.StormNo
,v1.StormYes
,v1.Equipment
,v2.TimeOn AS TimeOn
,v1.Vehicle
,v1.NAME
,v1.Equipment AS Equip
,v2.ScheduleOrig AS ScheduleOrig
,v2.ScheduleHTML AS ScheduleHTML
,v2.Schedule AS Schedule
,v2.TimeOff AS TimeOff
,v1.StormTimeOn
,v1.StormTimeOff
,v1.StormOut AS 'Out'
,v1.StormYes AS Yes
,v1.StormNo AS No
,v2.comments AS comments
,v1.StormComments
,v2.Comments AS CommentsHTML
,v1.Storm2
FROM [v_StormLog] v1
LEFT JOIN [v_StormLog] v2
ON v2.vehicle = v1.Vehicle
AND v2.CurrentDate = v1.CurrentDate
AND v2.Storm2 = 1
WHERE v1.[CurrentDate] >= @Date
AND v1.[CurrentDate] < DATEADD(dd,@Date,1)
AND v1.sgroup = 'North'
AND v1.Storm2 = @storm2
ORDER BY v1.ScheduleHTML
,v1.NAME
此外,这很糟糕:DATEADD(dd, DATEDIFF(dd, 0, v1.[CurrentDate]), 0) = @Date
。您告诉数据库加载每个日期时间值并对其执行此功能,然后将其与固定值进行比较。你想避免这种情况。您想 运行 您的函数针对静态值。这里,@Date
显然是一个以 00:00 作为时间分量的日期时间值。所以,在这种情况下,你可以这样做:
v1.[CurrentDate] >= @Date
AND v1.[CurrentDate] < DATEADD(dd,@Date,1)
这意味着 "CurrentDate is on or after @Date and before midnight of the day after @Date"。
我想加快这个查询的速度,我正在尝试各种连接,但我似乎无法结束对带有连接的 storm2 = 1 和 storm2 = 2 的重复查询
SELECT v1.id
,v1.StormOut
,v1.StormNo
,v1.StormYes
,v1.Equipment
,(
SELECT TimeOn
FROM [v_StormLog]
WHERE vehicle = v1.Vehicle
AND Storm2 = 1
AND CurrentDate = v1.CurrentDate
) AS TimeOn
,v1.Vehicle
,v1.NAME
,v1.Equipment AS Equip
,(
SELECT ScheduleOrig
FROM [v_StormLog]
WHERE vehicle = v1.Vehicle
AND Storm2 = 1
AND CurrentDate = v1.CurrentDate
) AS ScheduleOrig
,(
SELECT ScheduleHTML
FROM [v_StormLog]
WHERE vehicle = v1.Vehicle
AND Storm2 = 1
AND CurrentDate = v1.CurrentDate
) AS ScheduleHTML
,(
SELECT Schedule
FROM [v_StormLog]
WHERE vehicle = v1.Vehicle
AND Storm2 = 1
AND CurrentDate = v1.CurrentDate
) AS Schedule
,(
SELECT TimeOff
FROM [v_StormLog]
WHERE vehicle = v1.Vehicle
AND Storm2 = 1
AND CurrentDate = v1.CurrentDate
) AS TimeOff
,v1.StormTimeOn
,v1.StormTimeOff
,v1.StormOut AS 'Out'
,v1.StormYes AS Yes
,v1.StormNo AS No
,(
SELECT comments
FROM [v_StormLog]
WHERE vehicle = v1.Vehicle
AND Storm2 = 1
AND CurrentDate = v1.CurrentDate
) AS comments
,v1.StormComments
,(
SELECT Comments
FROM [v_StormLog]
WHERE vehicle = v1.Vehicle
AND Storm2 = 1
AND CurrentDate = v1.CurrentDate
) AS CommentsHTML
,v1.Storm2
FROM [v_StormLog] v1
WHERE DATEADD(dd, DATEDIFF(dd, 0, v1.[CurrentDate]), 0) = @Date
AND v1.sgroup = 'North'
AND v1.Storm2 = @storm2
ORDER BY v1.ScheduleHTML
,v1.NAME
您需要加入 table 本身。这将减少内部select的数量。您仍然应该检查执行计划是否有正确的索引
SELECT v1.*, v2.* -- update using the fields you need
FROM [v_StormLog] v1
JOIN [v_StormLog] v2
ON v2.vehicle = v1.Vehicle
AND v2.CurrentDate = v1.CurrentDate
WHERE
DATEADD(dd, DATEDIFF(dd, 0, v1.[CurrentDate]), 0) = @Date
AND v1.sgroup = 'North'
AND v1.Storm2 = @storm2
AND v2.Storm2 = 1
您还有重复的字段
,v1.StormOut
,v1.StormNo
,v1.StormYes
和
,v1.StormOut AS 'Out'
,v1.StormYes AS Yes
,v1.StormNo AS No
如果我没记错的话,那种子查询样式会转换为 OUTER JOIN,但是您应该检查您的执行计划以确定。假设是这样:
SELECT v1.id
,v1.StormOut
,v1.StormNo
,v1.StormYes
,v1.Equipment
,v2.TimeOn AS TimeOn
,v1.Vehicle
,v1.NAME
,v1.Equipment AS Equip
,v2.ScheduleOrig AS ScheduleOrig
,v2.ScheduleHTML AS ScheduleHTML
,v2.Schedule AS Schedule
,v2.TimeOff AS TimeOff
,v1.StormTimeOn
,v1.StormTimeOff
,v1.StormOut AS 'Out'
,v1.StormYes AS Yes
,v1.StormNo AS No
,v2.comments AS comments
,v1.StormComments
,v2.Comments AS CommentsHTML
,v1.Storm2
FROM [v_StormLog] v1
LEFT JOIN [v_StormLog] v2
ON v2.vehicle = v1.Vehicle
AND v2.CurrentDate = v1.CurrentDate
AND v2.Storm2 = 1
WHERE v1.[CurrentDate] >= @Date
AND v1.[CurrentDate] < DATEADD(dd,@Date,1)
AND v1.sgroup = 'North'
AND v1.Storm2 = @storm2
ORDER BY v1.ScheduleHTML
,v1.NAME
此外,这很糟糕:DATEADD(dd, DATEDIFF(dd, 0, v1.[CurrentDate]), 0) = @Date
。您告诉数据库加载每个日期时间值并对其执行此功能,然后将其与固定值进行比较。你想避免这种情况。您想 运行 您的函数针对静态值。这里,@Date
显然是一个以 00:00 作为时间分量的日期时间值。所以,在这种情况下,你可以这样做:
v1.[CurrentDate] >= @Date
AND v1.[CurrentDate] < DATEADD(dd,@Date,1)
这意味着 "CurrentDate is on or after @Date and before midnight of the day after @Date"。