如何使子查询更快地进行sql选择

时间:2014-11-19 19:08:04

标签: sql-server select

我有一个复杂的SQL select语句。它的性能非常差。我想知道如何让它更快。

SELECT 
     ............
     ............
     CASE WHEN (SELECT SUM(T.ONHAND) - SUM(T.RESERVED) FROM LV_001_01_STINVTOT T WHERE STOCKREF = S.LOGICALREF AND T.INVENNO IN (13,4)) < 0 THEN 0
          WHEN (SELECT SUM(T.ONHAND) - SUM(T.RESERVED) FROM LV_001_01_STINVTOT T WHERE STOCKREF = S.LOGICALREF AND T.INVENNO IN (13,4)) >= 0 
            THEN  (SELECT SUM(T.ONHAND) - SUM(T.RESERVED) FROM LV_001_01_STINVTOT T WHERE STOCKREF = S.LOGICALREF AND T.INVENNO IN (13,4))
     END AS MIKTAR
     ............
     ............
FROM XXX AS S

在上面的CASE中,我知道我使用了相同的子查询3次并使整个脚本太慢。

如何让它更快?

4 个答案:

答案 0 :(得分:0)

试试这个。使用left Join代替subquery

SELECT CASE
         WHEN Sum(T.ONHAND) - Sum(T.RESERVED) < 0 THEN 0
         ELSE Sum(T.ONHAND) - Sum(T.RESERVED)
       END
FROM   XXX s
      LEFT JOIN LV_001_01_STINVTOT T
         ON   t.STOCKREF = S.LOGICALREF
         AND  T.INVENNO IN ( 13, 4 ) 

SELECT CASE
         WHEN (SELECT Sum(T.ONHAND) - Sum(T.RESERVED)
               FROM   LV_001_01_STINVTOT T
               WHERE  STOCKREF = S.LOGICALREF
                      AND T.INVENNO IN ( 13, 4 )) < 0 THEN 0
         ELSE (SELECT Sum(T.ONHAND) - Sum(T.RESERVED)
               FROM   LV_001_01_STINVTOT T
               WHERE  STOCKREF = S.LOGICALREF
                      AND T.INVENNO IN ( 13, 4 ))
       END AS MIKTAR
FROM   XXX AS S 

或者声明一个变量将子查询结果存储在该变量中。

DECLARE @sumdiff INT

SELECT @sumdiff = Sum(T.ONHAND) - Sum(T.RESERVED)
FROM   LV_001_01_STINVTOT T
WHERE  STOCKREF = S.LOGICALREF
       AND T.INVENNO IN ( 13, 4 )

SELECT CASE 
         WHEN @sumdiff< 0 THEN 0
         ELSE @sumdiff
       END
FROM   XXX s 

答案 1 :(得分:0)

你可以尝试这样的事情。请注意,SQL Server 2012及更高版本中提供了IIF功能。

SELECT 
IIF (SUM(ISNULL(T.ONHAND,0)) - SUM(ISNULL(T.RESERVED,0)) < 0, 0, SUM(T.ONHAND) - SUM(T.RESERVED) )
FROM XXX AS S
LEFT JOIN LV_001_01_STINVTOT T ON STOCKREF = S.LOGICALREF AND T.INVENNO IN (13,4)

答案 2 :(得分:0)

SELECT 
     CASE  WHEN SUM(T.ONHAND) - SUM(T.RESERVED) < 0 THEN 0
         ELSE SUM(T.ONHAND) - SUM(T.RESERVED)
     END AS MIKTAR
FROM XXX AS S
LEFT JOIN LV_001_01_STINVTOT T  ON  T.STOCKREF = S.LOGICALREF  
                               AND  T.INVENNO IN (13,4)

答案 3 :(得分:0)

您可以尝试这样的事情。

SELECT 
    CASE WHEN AVAILABLESTOCK<0 THEN 0
    WHEN RESULT>= 0 THEN ...
FROM XXX AS S,
(SELECT SUM(T.ONHAND)-SUM(T.RESERVED) AS AVAILABLESTOCK,STOCKREF  FROM LV_001_01_STINVTOT WHERE T.INVENNO IN (13,4)
GROUP BY STOCKREF ) LV
WHERE S.LOGICALREF =LV.STOCKREF

您还可以尝试在Temp表中保存LV_001_01_STINVTOT的聚合结果,并在子查询中使用该临时表。它取决于LV_001_01_STINVTOT的实际大小及其大小与聚合后的条件“T.INVENNO IN(13,4)”