-2

期間がそれほど長くなくても、実行に2分かかる次のクエリがあります。

SELECT MTI.DeptID,
       ShortEmployees.EmpID,
       ShortEmployees.EmpName1 AS EmpName,
       Sum(CASE
             WHEN (BSR.BSTID = 3
                   AND bli.state IN (12, 13, 14)) THEN -1 * ((BLD.Qty / dbo.Getunitval(BLD.UnitID, BLD.MTID)) * BLD.Price - ((BLD.Qty / dbo.Getunitval(BLD.UnitID, BLD.MTID)) * BLD.Price * BLD.discount * 0.01))
             ELSE ((BLD.Qty / dbo.Getunitval(BLD.UnitID, BLD.MTID)) * BLD.Price - ((BLD.Qty / dbo.Getunitval(BLD.UnitID, BLD.MTID)) * BLD.Price * BLD.discount * 0.01))
           END) AS Total
FROM   BLD
       INNER JOIN BLI
         ON BLD.BLNo = BLI.BLNo
       INNER JOIN BSR
         ON BLI.BLID = BSR.BLID
       INNER JOIN ShortEmployees
         ON BLI.EmpID = ShortEmployees.EmpID
       INNER JOIN MTI
         ON BLD.MTID = MTI.MTID
WHERE  (MTI.DeptID = 'B')
       AND (BLI.BLDate > Cast('2013-01-01 00:00:00' AS DATETIME))
       AND (BLI.BLDate < Cast('2013-01-14 23:59:59' AS DATETIME))
       AND ((BSR.BSTID = 2
             AND bli.state IN (2, 6, 8, 9,
                               10, 12, 18))
             OR (BSR.BSTID = 3
                 AND bli.state IN (12, 13, 14)))
GROUP  BY ShortEmployees.EmpName1,
          ShortEmployees.EmpID,
          MTI.DeptID
ORDER  BY Total DESC

どうすれば最適化できますか?

MTI: アイテム情報テーブル。

BLI: 請求表。

BLD: 請求詳細テーブル。

ShortEmployees: セールスマン テーブル。

4

3 に答える 3

1

すべての結合が行われた後にフィルタリングするのではなく、結合が行われるときに条件を適用できる JOKN ON 句に条件を移動します。

SELECT MTI.DeptID,
       ShortEmployees.EmpID,
       ShortEmployees.EmpName1 AS EmpName,
       Sum(CASE
             WHEN (BSR.BSTID = 3
                   AND bli.state IN (12, 13, 14)) THEN -1 * ((BLD.Qty / dbo.Getunitval(BLD.UnitID, BLD.MTID)) * BLD.Price - ((BLD.Qty / dbo.Getunitval(BLD.UnitID, BLD.MTID)) * BLD.Price * BLD.discount * 0.01))
             ELSE ((BLD.Qty / dbo.Getunitval(BLD.UnitID, BLD.MTID)) * BLD.Price - ((BLD.Qty / dbo.Getunitval(BLD.UnitID, BLD.MTID)) * BLD.Price * BLD.discount * 0.01))
           END) AS Total
FROM BLD
JOIN BLI ON BLD.BLNo = BLI.BLNo
    AND BLI.BLDate BETWEEN Cast('2013-01-01 00:00:00' AS DATETIME)
       AND Cast('2013-01-14 23:59:59' AS DATETIME)
JOIN BSR ON BLI.BLID = BSR.BLID
    AND ((BSR.BSTID = 2
             AND bli.state IN (2, 6, 8, 9, 10, 12, 18)
        OR (BSR.BSTID = 3
             AND bli.state IN (12, 13, 14))
JOIN ShortEmployees ON BLI.EmpID = ShortEmployees.EmpID
JOIN MTI ON BLD.MTID = MTI.MTID
    AND MTI.DeptID = 'B'
GROUP BY ShortEmployees.EmpName1,
    ShortEmployees.EmpID,
    MTI.DeptID
ORDER BY Total DESC

クエリが期間の最初と最後の秒を除外したため、日付範囲チェックを BETWEEN に変更したことに注意してください。

不要な括弧とインデントも削除しました

于 2013-01-14T09:36:32.990 に答える
0

最後に、そのクエリをストアド プロシージャ全体に変換することになりましたが、その違いは非常に大きいです。今では 2 秒しかかかりません :)、みんな、特に嫌いなスパンキーに感謝します ;)

于 2013-01-17T05:52:59.043 に答える