替换sql server子查询以使查询更快而不是爬行

时间:2015-11-04 21:19:18

标签: sql sql-server sql-server-2008 subquery

我想加快这个查询速度,我正在尝试各种连接,但我似乎不会因为连接而没有结束对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

2 个答案:

答案 0 :(得分:1)

您需要自己加入桌子。这将减少内部选择的数量。您仍应检查是否有正确的索引查看执行计划

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

答案 1 :(得分:1)

如果我没记错的话,那种子查询样式会被转换为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)

这意味着&#34; CurrentDate在@Date之后或之后以及@ Date&#34;之后的一天午夜之前。