为什么SQL查询需要更长时间作为子查询

时间:2018-03-15 08:28:15

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

我尝试运行SQL查询:

SELECT (SELECT
    SUM(fldAmount)
  FROM tblSession s
  LEFT JOIN tblTransMain m
    ON s.fldStore = m.fldStore
    AND s.fldSessionID = m.fldSessionID
  LEFT JOIN tblTransPayments t
    ON m.fldStore = t.fldStore
    AND m.fldSequence = t.fldSequence
  WHERE s.fldStore = 3
  AND s.fldDrawer = 8003)

需要很长时间(约30-40秒)

如果我删除第一个SELECT - 查询需要0.05毫秒 我需要第一个选择,因为我需要运行的实际查询更复杂:

SELECT (SELECT
    SUM(fldAmount)
  FROM tblSession s
  LEFT JOIN tblTransMain m
    ON s.fldStore = m.fldStore
    AND s.fldSessionID = m.fldSessionID
  LEFT JOIN tblTransPayments t
    ON m.fldStore = t.fldStore
    AND m.fldSequence = t.fldSequence
  WHERE s.fldStore = 3
  AND s.fldDrawer = 8003
  AND p.fldID = t.fldPaymeansGroup)
FROM tblPaymeansGroups p

3 个答案:

答案 0 :(得分:0)

您可以尝试使用不相关的子查询重写您的查询:

SELECT p.*, a.fldAmount
FROM tblPaymeansGroups p
INNER JOIN
(
    SELECT t.fldPaymeansGroup, SUM(fldAmount) AS fldAmount
    FROM tblSession s
    LEFT JOIN tblTransMain m
        ON s.fldStore = m.fldStore AND
           s.fldSessionID = m.fldSessionID
    LEFT JOIN tblTransPayments t
        ON m.fldStore = t.fldStore AND
           m.fldSequence = t.fldSequence
    WHERE
        s.fldStore = 3 AND
        s.fldDrawer = 8003 AND
        p.fldID = t.fldPaymeansGroup
    GROUP BY t.fldPaymeansGroup
) a
    ON p.fldID = a.fldPaymeansGroup

答案 1 :(得分:0)

试试这个:

  SELECT (SELECT SUM(fldAmount) FROM tblSession s
  LEFT JOIN tblTransMain m  ON s.fldSessionID = m.fldSessionID
  LEFT JOIN tblTransPayments t ON m.fldSequence = t.fldSequence
  WHERE s.fldStore = 3 and m.fldStore = 3 and t.fldStore =3
  AND s.fldDrawer = 8003 AND p.fldID = t.fldPaymeansGroup)

答案 2 :(得分:0)

对于此查询:

SELECT (SELECT SUM(fldAmount)
        FROM tblSession s LEFT JOIN
             tblTransMain m
             ON s.fldStore = m.fldStore and
                s.fldSessionID = m.fldSessionID LEFT JOIN
             tblTransPayments t
             ON m.fldStore = t.fldStore AND
             m.fldSequence = t.fldSequence
        WHERE s.fldStore = 3 AND
              s.fldDrawer = 8003 AND
              p.fldID = t.fldPaymeansGroup
       )
FROM tblPaymeansGroups p

首先,不需要LEFT JOIN。由于t上的过滤,其列不能是NULL。因此,首先将其写为INNER JOIN

SELECT (SELECT SUM(fldAmount)
        FROM tblSession s JOIN
             tblTransMain m
             ON s.fldStore = m.fldStore and
                s.fldSessionID = m.fldSessionID JOIN
             tblTransPayments t
             ON m.fldStore = t.fldStore AND
                m.fldSequence = t.fldSequence
        WHERE s.fldStore = 3 AND
              s.fldDrawer = 8003 AND
              p.fldID = t.fldPaymeansGroup
       )
FROM tblPaymeansGroups p

接下来,您需要索引:

  • tblTransPayments(fldPaymeansGroup, fldSequence, fldStore)
  • tblTransMain(fldStore, fldSequence, fldSessionID)
  • tblSession(fldStore, fldSequence, fldDrawer)

您还可以将fldAmount放入相应表的索引(作为最后一个键)。