我对一个需要花费几个小时才能运行的视图进行了大量查询,我觉得有可能对其性能进行处理"有点" ..
问题在于我不确定应该做什么。查询SELECT
39 值,LEFT OUTER JOIN
25 表和每个表最多可包含几个百万行
任何提示都很好。有没有什么好方法可以解决这个问题?我试着用更少的数据(花了大约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 ...
答案 0 :(得分:2)
将您的问题分解为可管理的部分。如果执行计划太大而无法进行分析,请从查询的较小部分开始,检查其执行计划并对其进行优化。
关于如何优化查询没有一般性的答案,因为查询可能很慢的原因有很多。你必须检查执行计划。
通常,提高绩效的最有希望的方法是:
<强>索引:强>
当您看到群集索引扫描或 - 甚至更糟(因为您没有群集索引)时 - 查询计划中的表扫描您加入的表,您需要一个JOIN
谓词的索引。如果您拥有包含数百万条目的表,并且只选择这些条目的一小部分,则尤其如此。还要检查执行计划中的索引建议。
当您的聚集索引扫描变成索引搜索时,您会看到该索引有效。
索引包括:
您可能正在显示已加入的表中与您用于加入的字段不同的列(否则,您为什么需要加入?)。 SQL Server需要从表中获取所需的字段,您在执行计划中将其视为 Key Lookup 。
由于您从25个表中获取了39个值,因此每个表中只需要很少的字段(大多数是一个或两个)。 SQL Server需要加载respecitive表的整个页面并从中获取值。
在这种情况下,您应该INCLUDE
要在索引中显示的列以避免键查找。这是因为索引大小增加了,但考虑到您只包含几个列,与表的大小相比,这个成本应该可以忽略不计。
检查您加入的观看次数:
当你加入VIEW
时,你应该知道它基本上意味着你的查询的扩展(这也意味着执行计划)。对视图执行与主查询相同的性能优化。另外,检查是否在已加入主查询的视图中连接表。这些联接可能是不必要的。
索引视图(可能):
通常,您可以为要加入查询的视图添加索引,也可以为查询的某些部分创建一个或多个索引视图。但有一些警告:
OUTER JOIN
被禁止。如果您可以将至少部分OUTER JOIN
转换为INNER JOIN
,这可能是一种选择。加入索引视图时,请不要忘记在联接中使用WITH(NOEXPAND)
,否则可能会忽略它们。
分区表(可能):
如果您在SQL Server企业版上运行,则可以对表进行分区。如果您加入的行始终从可用行的一小部分中选择,那么这将非常有用。您可以为此子集创建分区并提高性能。
<强>要点:强>
分而治之。逐位分析您的查询以优化它。最有前途的选择是索引和索引包括。如果你还有问题,请从那里开始。