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。
正在检查您加入的视图:
当您加入 VIEW
s 时,您应该知道它基本上意味着对您的查询的扩展(这也意味着执行计划)。对视图进行与对主查询相同的性能优化。此外,检查您是否在已加入主查询的视图中加入 tables。这些联接可能是不必要的。
索引视图(可能):
通常,您可以将索引添加到要加入查询的视图中,或者为部分查询创建一个或多个索引视图。不过有一些注意事项:
- 索引视图在您的数据库中占用 space 存储空间,因为您多次存储部分数据。
- 有 a lot of restrictions 索引视图,最值得注意的是在您的情况下
OUTER JOIN
是被禁止的。如果您至少可以将部分 OUTER JOIN
转换为 INNER JOIN
,这可能是一个选择。
加入索引视图时,不要忘记在加入中使用 WITH(NOEXPAND)
,否则它们可能会被忽略。
分区tables(可能):
如果您 运行 在 SQL 服务器的企业版上,您可以对 table 进行分区。如果您加入的行总是 select 来自可用行的一小部分,这将很有用。您可以为该子集创建分区并提高性能。
总结:
分而治之。一点一点地分析您的查询以优化它。最有前途的选择是索引和索引包含。如果您仍然遇到问题,请从那里开始。
我对需要几个小时才能完成的视图有一个很大的查询 运行,我觉得可能可以改善它的性能 "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。
正在检查您加入的视图:
当您加入 VIEW
s 时,您应该知道它基本上意味着对您的查询的扩展(这也意味着执行计划)。对视图进行与对主查询相同的性能优化。此外,检查您是否在已加入主查询的视图中加入 tables。这些联接可能是不必要的。
索引视图(可能):
通常,您可以将索引添加到要加入查询的视图中,或者为部分查询创建一个或多个索引视图。不过有一些注意事项:
- 索引视图在您的数据库中占用 space 存储空间,因为您多次存储部分数据。
- 有 a lot of restrictions 索引视图,最值得注意的是在您的情况下
OUTER JOIN
是被禁止的。如果您至少可以将部分OUTER JOIN
转换为INNER JOIN
,这可能是一个选择。
加入索引视图时,不要忘记在加入中使用 WITH(NOEXPAND)
,否则它们可能会被忽略。
分区tables(可能):
如果您 运行 在 SQL 服务器的企业版上,您可以对 table 进行分区。如果您加入的行总是 select 来自可用行的一小部分,这将很有用。您可以为该子集创建分区并提高性能。
总结:
分而治之。一点一点地分析您的查询以优化它。最有前途的选择是索引和索引包含。如果您仍然遇到问题,请从那里开始。