SQL 服务器视图中大查询的性能

Performance for big query in SQL Server view

我对需要几个小时才能完成的视图有一个很大的查询 运行,我觉得可能可以改善它的性能 "a bit"..

问题是我不确定我应该做什么。查询 SELECT 39 值,LEFT OUTER JOIN 25 tables 和每个 table 可以最多有几 百万行 .

任何提示都是好的。有什么好的方法可以解决这个问题吗?我试图查看数据较少的测试的实际执行计划 (花了大约 10 分钟到 运行) 但它非常大。我可以做些什么来加快速度吗?我必须同时处理一小部分吗?

也许只有一个连接会减慢一切?我如何检测它?那么简而言之,我该如何处理这样的查询?

如前所述,所有反馈都很好。有没有更多的信息需要我展示,告诉我!

查询看起来像这样:

SELECT DISTINCT 
    A.something,
    A.somethingElse,
    B.something,
    C.somethingElse,
    ISNULL(C.somethingElseElse, '')
    C.somethingElseElseElse,
    CASE *** THEN D.something ELSE 0,
    E.something,
    ...
    U.something
FROM 
    TableA A 
JOIN 
    TableB B on ...
JOIN 
    TableC C on ...
JOIN 
    TableD D on ...
JOIN 
    TableE E on ...
JOIN 
    TableF F on ...
JOIN 
    TableG G on ...
...
JOIN 
    Table U on ...

将您的问题分解成可管理的部分。如果执行计划太大,您无法分析,请从查询的较小部分开始,检查其执行计划并对其进行优化。

没有关于如何优化查询的通用答案,因为有一大堆可能导致查询变慢的原因。你必须检查执行计划。

通常最有希望提高性能的方法是:

索引:

当您看到 聚簇索引扫描 或 - 更糟(因为那时您没有聚簇索引) - Table在您的查询计划中扫描 以查找您加入的 table,您需要为您的 JOIN 谓词建立索引。如果您的 table 包含数百万个条目,而您 select 只是这些条目的一小部分,则尤其如此。还要检查执行计划中的索引建议。

当您的 Clustered Index Scan 变成 Index Seek.

时,您会看到索引起作用了

索引包括:

您可能正在显示您加入的 table 中的列,这些列与您用于加入的字段不同(否则,您为什么需要加入?)。 SQL 服务器需要从 table 中获取您需要的字段,您在执行计划中看到的是 Key Lookup.

由于您要从 25 个 table 中获取 39 个值,因此每个 table 您需要获取的字段很少(主要是一两个)。 SQL 服务器需要加载相应 table 的整个页面并从中获取值。

在这种情况下,您应该 INCLUDE 要在索引中显示的列以避免键查找。这会增加索引大小,但考虑到您只包含几列,与 tables 的大小相比,该成本应该可以忽略不计 table。

正在检查您加入的视图:

当您加入 VIEWs 时,您应该知道它基本上意味着对您的查询的扩展(这也意味着执行计划)。对视图进行与对主查询相同的性能优化。此外,检查您是否在已加入主查询的视图中加入 tables。这些联接可能是不必要的。

索引视图(可能):

通常,您可以将索引添加到要加入查询的视图中,或者为部分查询创建一个或多个索引视图。不过有一些注意事项:

  1. 索引视图在您的数据库中占用 space 存储空间,因为您多次存储部分数据。
  2. a lot of restrictions 索引视图,最值得注意的是在您的情况下 OUTER JOIN 是被禁止的。如果您至少可以将部分 OUTER JOIN 转换为 INNER JOIN,这可能是一个选择。

加入索引视图时,不要忘记在加入中使用 WITH(NOEXPAND),否则它们可能会被忽略。

分区tables(可能):

如果您 运行 在 SQL 服务器的企业版上,您可以对 table 进行分区。如果您加入的行总是 select 来自可用行的一小部分,这将很有用。您可以为该子集创建分区并提高性能。

总结:

分而治之。一点一点地分析您的查询以优化它。最有前途的选择是索引和索引包含。如果您仍然遇到问题,请从那里开始。