如何使用子查询优化复杂的SQL查询/视图

Sam*_*Sam -1 sql sql-server

我有一个非常复杂的SQL视图.我的问题是,当我想要报告时,它非常慢并且需要大量内存.View的作用:它查询一个总值并将其乘以一个因子显然它是因为它包含很多子查询...(如果算上它则为9)

查询在具有数百万个数据集的系统上运行.

我的问题.哪些点可以优化呢?如果我制作准备好的程序或者为子查询创建sql视图会更快吗?

SELECT 
    CASE BID WHEN 1 THEN 
        b.TOTAL 
    ELSE 
        (b.TOTAL * - 1) 
    END 
    * 
    CASE WHEN
        (SELECT 
            (CAST(DATEDIFF(day, 
                ISNULL
                ((SELECT dbo.TableA.TimestampFrom + 1 AS start FROM dbo.TableB INNER JOIN
                    dbo.TableA ON dbo.TableB.SID = dbo.TableA.SID
                    WHERE   (dbo.TableB.PID = dbo.TableC.PID) AND
                        (dbo.TableB.MString = 'S' OR dbo.TableB.MString = 'ST') AND
                        (dbo.TableB.TimestampCreated <
                            (SELECT TimestampCreated
                                FROM dbo.TableB AS TableB_2
                            WHERE (RID = dbo.TableC.RID)))
                        AND
                            (dbo.TableB.VPFrom =
                                    (SELECT VPFrom FROM dbo.TableB AS TableB_1
                                            WHERE (RID = dbo.TableC.RID))
                            )), VPFrom), VPTo)
                            AS Float) + 1)
            / 
            (CAST(DATEDIFF(day, start, Vertragsende) AS Float) + 1) AS Faktor

            FROM dbo.TableC
                WHERE (LaufNr = b.LaufNr))
                    > 1 
        THEN 
            1 
        ELSE
            (SELECT (CAST(DATEDIFF(day, 
                ISNULL
                    ((SELECT dbo.TableA.TimestampFrom + 1 AS start FROM dbo.TableB INNER JOIN
                            dbo.TableA ON dbo.TableB.SID =  dbo.TableA.SID
                            WHERE (dbo.TableB.PID = dbo.TableC.PID) AND
                                (dbo.TableB.MString = 'S' OR dbo.TableB.MString = 'ST') AND
                                (dbo.TableB.TimestampCreated <
                                    (SELECT TimestampCreated FROM dbo.TableB AS TableB_2
                                     WHERE (RID = dbo.TableC.RID)))
                                AND (dbo.TableB.VPFrom =
                                    (SELECT VPFrom FROM dbo.TableB AS TableB_1
                                    WHERE (RID = dbo.TableC.RID)))
                        ), VPFrom),VPTo) AS Float) + 1)
                / (CAST(DATEDIFF(day, start, Vertragsende) AS Float) + 1) AS Faktor 
                FROM dbo.TableC
                WHERE (LaufNr = b.LaufNr)) 
        END AS GrossPremium
    ,RID, PID, ONR, OPosLaufNr, LaufNr, bdate
FROM dbo.TableC AS b
Run Code Online (Sandbox Code Playgroud)

Mik*_*ll' 5

索引的经验法则是

  • 首先,阅读执行计划,

然后考虑添加一个索引

  • WHERE子句中使用的每一列,
  • 在JOIN条件中使用的每一列,
  • ORDER BY中使用的每一列.

在某些情况下,SELECT语句中的一个多列索引比几个单列索引更快.

然后,确保您的WHERE子句是可搜索的.

最后,尝试将一些子查询转换为视图以进行测试是有意义的.我的猜测是问题的根本原因是你正在执行不同的子查询,具体取决于几个CASE语句的返回值.