需要帮助优化sql查询吗

需要帮助优化sql查询吗,sql,sql-server,Sql,Sql Server,我有一个跟踪共同基金投资的网站。为此,我对下表的结构进行了修改,以删除不需要的列,从而将重点放在我的问题上 表1:方案(Mst) 表2投资 表3赎回 表4交换机详细信息 表5骨量详情 表6详细分类 现在,我想了解一下该方案中可用单元的详细信息,我在下面的查询中提出了……这非常昂贵 SELECT *, CASE WHEN OutstandingUnits <> 0 THEN CONVERT(decimal(18,2),Outstanding/Outs

我有一个跟踪共同基金投资的网站。为此,我对下表的结构进行了修改,以删除不需要的列,从而将重点放在我的问题上

表1:方案(Mst)

表2投资

表3赎回

表4交换机详细信息

表5骨量详情

表6详细分类

现在,我想了解一下该方案中可用单元的详细信息,我在下面的查询中提出了……这非常昂贵

SELECT *,
       CASE
           WHEN OutstandingUnits <> 0 THEN CONVERT(decimal(18,2),Outstanding/OutstandingUnits)
           ELSE 0
       END AS WAC
FROM
  (SELECT *,
          ISNULL(OpeningBalance,0) + ISNULL(DividendAmount,0) + ISNULL(bonusAmount,0) + ISNULL(invstAmount,0) + ISNULL(SwitchedInAmount,0) - ISNULL(redeemedAmount,0) - ISNULL(SwitchedOutAmount,0) AS Outstanding,
          ISNULL(openingUnits,0) + ISNULL(DividendUnits,0) + ISNULL(bonusUnits,0) + ISNULL(invstUnits,0) + SNULL(SwitchedInUnits,0) - ISNULL(redeemedUnits,0) - ISNULL(SwitchedOutUnits,0) AS OutstandingUnits
   FROM
     (SELECT C.scheme_ID,D.schemeName, D.Openingbalance AS OpeningBalance, D.OpeningUnits AS openingUnits, ISNULL(SUM(C.invstAmount),0) AS invstAmount, ISNULL(SUM(C.invstUnits),0) AS invstUnits,
        (SELECT ISNULL(SUM(redemedAmt),0)
         FROM redemption
         WHERE StatusFlag='A'
           AND scheme_ID = C.scheme_ID) AS redeemedAmount,
        (SELECT ISNULL(SUM(redeemedUnits),0)
         FROM redemption
         WHERE StatusFlag='A'
           AND scheme_ID = C.scheme_ID) AS redeemedUnits,
        (SELECT ISNULL(sum(switchOutAmt),0)
         FROM SwitchDetails
         WHERE BB.Status = 'A'
           AND BB.From_Scheme_Id = C.scheme_ID) AS SwitchedOutAmount,
        (SELECT ISNULL(sum(switchOutUnits),0)
         FROM SwitchDetails
         WHERE BB.Status = 'A'
           AND BB.From_Scheme_Id = C.scheme_ID) AS SwitchedOutUnits,
        (SELECT ISNULL(sum(switchOutAmt),0)
         FROM SwitchDetails
         WHERE BB.Status = 'A'
           AND BB.From_Scheme_Id = C.scheme_ID) AS SwitchedInAmount,
        (SELECT ISNULL(sum(SwitchedInUnits),0)
         FROM SwitchDetails
         WHERE BB.Status = 'A'
           AND BB.From_Scheme_Id = C.scheme_ID) AS SwitchedInUnits, .. same way
      FOR bonus
      AND divident ..
      FROM Investment c) tab)tab2
这就是我计算细节的方式。请告诉我更好的方法


我正在使用sql server 2008

在这种情况下,具有相同条件的子查询可能是最糟糕的性能敌人

对于内部查询,请尝试以下操作:

SELECT 
    c.scheme_ID,
    d.schemeName,
    d.Openingbalance AS OpeningBalance,
    d.OpeningUnits AS openingUnits,
    ISNULL(SUM(c.invstAmount), 0) AS invstAmount,
    ISNULL(SUM(c.invstUnits), 0) AS invstUnits,

    ISNULL(SUM(r.redemedAmt), 0) AS redeemedAmount,
    ISNULL(SUM(r.redeemedUnits), 0) AS redeemedUnits, 
    ISNULL(SUM(r.switchOutAmt), 0) AS SwitchedOutAmount,
    ISNULL(SUM(r.switchOutUnits), 0) AS SwitchedOutUnits,
    ISNULL(SUM(r.switchOutAmt), 0) AS SwitchedInAmount,
    ISNULL(SUM(r.SwitchedInUnits), 0) AS SwitchedInUnits
FROM Investment AS c
INNER JOIN redemption AS r 
    ON r.StatusFlag='A' AND r.scheme_ID = C.scheme_ID
--INNER JOIN someTable AS d...

您可以这样做我没有插入GROUP BY子句或sum Openingbalance,OpeningUnits您更了解您的查询逻辑,我只是为了性能而编辑:

SELECT *,
       CASE
           WHEN OutstandingUnits <> 0 THEN CONVERT(decimal(18,2),Outstanding/OutstandingUnits)
           ELSE 0
       END AS WAC
FROM
     (SELECT C.scheme_ID,
             D.schemeName, 
             D.Openingbalance AS OpeningBalance, 
             D.OpeningUnits AS openingUnits, 
             ISNULL(SUM(C.invstAmount),0) AS invstAmount, 
             ISNULL(SUM(C.invstUnits),0) AS invstUnits,
         ISNULL(SUM(r.redemedAmt),0) redeemedAmount,
         ISNULL(SUM(r.redeemedUnits),0) redeemedUnits,
         ISNULL(sum(sd.switchOutAmt),0) SwitchedOutAmount,
         ISNULL(sum(sd.switchOutUnits),0) SwitchedOutUnits,
         ISNULL(sum(sd.switchOutAmt),0) SwitchedInAmount,
         ISNULL(sum(sd.SwitchedInUnits),0) SwitchedInUnits,
          --The sum columns from above query
          ISNULL(OpeningBalance,0) + ISNULL(DividendAmount,0) + ISNULL(bonusAmount,0) + ISNULL(invstAmount,0) + 
          ISNULL(SwitchedInAmount,0) - ISNULL(redeemedAmount,0) - ISNULL(SwitchedOutAmount,0) AS Outstanding,
          ISNULL(openingUnits,0) + ISNULL(DividendUnits,0) + ISNULL(bonusUnits,0) + ISNULL(invstUnits,0) + 
          ISNULL(SwitchedInUnits,0) - ISNULL(redeemedUnits,0) - ISNULL(SwitchedOutUnits,0) AS OutstandingUnits,
          ----
      .. same way
      FOR bonus
      AND divident ..
      FROM Investment c
      LEFT JOIN redemption r
       ON r.StatusFlag='A'
       AND r.scheme_ID = C.scheme_ID
      LEFT JOIN SwitchDetails sd
       ON sd.Status = 'A'
       AND sd.From_Scheme_Id = C.scheme_ID
       ) tab

您需要使用联接,而不是子查询SwitchedOutAmount之后的每个子查询上的where与它们引用的switchedetails表无关-因此这些数字将对整个表求和…如果您有许多并行的1-N关系,然后,您可能必须使用子查询分组可能会重复行,但即使这样,您也可以在单个子查询中聚合许多值,例如选择sum作为a1,sum作为2。。。from…,您可以创建数据的平面视图或sql server的平面视图。当在查询中使用select*from select*from table as x时,实际上您不再使用表,而是使用视图,请使用内部联接来提高性能。在表上添加索引也会加快查询速度,只选择需要的字段,其余的将要求额外的内存等。。。
|From_Scheme_ID |To_Scheme_ID |switchInAmt |switchInUnits |switchOutAmt |switchOutUnits | StaFlag
------------------------------------------------------------------------------------------
|1              | 2           | 20         | 2            | 10          | 1             | A
|Scheme_ID | BonusAmt   | BonusUnits | statusFlag
----------------------------------------------------------
|1         | 50         |  5         | A
|Scheme_ID | DividentAmt | DividentUnits | statusFlag
----------------------------------------------------------
|1         | 50          |  5            | A
SELECT *,
       CASE
           WHEN OutstandingUnits <> 0 THEN CONVERT(decimal(18,2),Outstanding/OutstandingUnits)
           ELSE 0
       END AS WAC
FROM
  (SELECT *,
          ISNULL(OpeningBalance,0) + ISNULL(DividendAmount,0) + ISNULL(bonusAmount,0) + ISNULL(invstAmount,0) + ISNULL(SwitchedInAmount,0) - ISNULL(redeemedAmount,0) - ISNULL(SwitchedOutAmount,0) AS Outstanding,
          ISNULL(openingUnits,0) + ISNULL(DividendUnits,0) + ISNULL(bonusUnits,0) + ISNULL(invstUnits,0) + SNULL(SwitchedInUnits,0) - ISNULL(redeemedUnits,0) - ISNULL(SwitchedOutUnits,0) AS OutstandingUnits
   FROM
     (SELECT C.scheme_ID,D.schemeName, D.Openingbalance AS OpeningBalance, D.OpeningUnits AS openingUnits, ISNULL(SUM(C.invstAmount),0) AS invstAmount, ISNULL(SUM(C.invstUnits),0) AS invstUnits,
        (SELECT ISNULL(SUM(redemedAmt),0)
         FROM redemption
         WHERE StatusFlag='A'
           AND scheme_ID = C.scheme_ID) AS redeemedAmount,
        (SELECT ISNULL(SUM(redeemedUnits),0)
         FROM redemption
         WHERE StatusFlag='A'
           AND scheme_ID = C.scheme_ID) AS redeemedUnits,
        (SELECT ISNULL(sum(switchOutAmt),0)
         FROM SwitchDetails
         WHERE BB.Status = 'A'
           AND BB.From_Scheme_Id = C.scheme_ID) AS SwitchedOutAmount,
        (SELECT ISNULL(sum(switchOutUnits),0)
         FROM SwitchDetails
         WHERE BB.Status = 'A'
           AND BB.From_Scheme_Id = C.scheme_ID) AS SwitchedOutUnits,
        (SELECT ISNULL(sum(switchOutAmt),0)
         FROM SwitchDetails
         WHERE BB.Status = 'A'
           AND BB.From_Scheme_Id = C.scheme_ID) AS SwitchedInAmount,
        (SELECT ISNULL(sum(SwitchedInUnits),0)
         FROM SwitchDetails
         WHERE BB.Status = 'A'
           AND BB.From_Scheme_Id = C.scheme_ID) AS SwitchedInUnits, .. same way
      FOR bonus
      AND divident ..
      FROM Investment c) tab)tab2
Scheme_ID| Scheme_Name | OpeningBalance | OpeningUnits | InvstAmount | invstUnits | redemedAmount | redemedUnits | SwitchedOutAmt | SwitchOutUnit | bonusAmt | bonusUnit | DividentAmount | DividentUnit | Outstanding | OutstandingUnit | WAC
-------------------------------------------------------------------------------------------
SELECT 
    c.scheme_ID,
    d.schemeName,
    d.Openingbalance AS OpeningBalance,
    d.OpeningUnits AS openingUnits,
    ISNULL(SUM(c.invstAmount), 0) AS invstAmount,
    ISNULL(SUM(c.invstUnits), 0) AS invstUnits,

    ISNULL(SUM(r.redemedAmt), 0) AS redeemedAmount,
    ISNULL(SUM(r.redeemedUnits), 0) AS redeemedUnits, 
    ISNULL(SUM(r.switchOutAmt), 0) AS SwitchedOutAmount,
    ISNULL(SUM(r.switchOutUnits), 0) AS SwitchedOutUnits,
    ISNULL(SUM(r.switchOutAmt), 0) AS SwitchedInAmount,
    ISNULL(SUM(r.SwitchedInUnits), 0) AS SwitchedInUnits
FROM Investment AS c
INNER JOIN redemption AS r 
    ON r.StatusFlag='A' AND r.scheme_ID = C.scheme_ID
--INNER JOIN someTable AS d...
SELECT *,
       CASE
           WHEN OutstandingUnits <> 0 THEN CONVERT(decimal(18,2),Outstanding/OutstandingUnits)
           ELSE 0
       END AS WAC
FROM
     (SELECT C.scheme_ID,
             D.schemeName, 
             D.Openingbalance AS OpeningBalance, 
             D.OpeningUnits AS openingUnits, 
             ISNULL(SUM(C.invstAmount),0) AS invstAmount, 
             ISNULL(SUM(C.invstUnits),0) AS invstUnits,
         ISNULL(SUM(r.redemedAmt),0) redeemedAmount,
         ISNULL(SUM(r.redeemedUnits),0) redeemedUnits,
         ISNULL(sum(sd.switchOutAmt),0) SwitchedOutAmount,
         ISNULL(sum(sd.switchOutUnits),0) SwitchedOutUnits,
         ISNULL(sum(sd.switchOutAmt),0) SwitchedInAmount,
         ISNULL(sum(sd.SwitchedInUnits),0) SwitchedInUnits,
          --The sum columns from above query
          ISNULL(OpeningBalance,0) + ISNULL(DividendAmount,0) + ISNULL(bonusAmount,0) + ISNULL(invstAmount,0) + 
          ISNULL(SwitchedInAmount,0) - ISNULL(redeemedAmount,0) - ISNULL(SwitchedOutAmount,0) AS Outstanding,
          ISNULL(openingUnits,0) + ISNULL(DividendUnits,0) + ISNULL(bonusUnits,0) + ISNULL(invstUnits,0) + 
          ISNULL(SwitchedInUnits,0) - ISNULL(redeemedUnits,0) - ISNULL(SwitchedOutUnits,0) AS OutstandingUnits,
          ----
      .. same way
      FOR bonus
      AND divident ..
      FROM Investment c
      LEFT JOIN redemption r
       ON r.StatusFlag='A'
       AND r.scheme_ID = C.scheme_ID
      LEFT JOIN SwitchDetails sd
       ON sd.Status = 'A'
       AND sd.From_Scheme_Id = C.scheme_ID
       ) tab