2

我有一个需要加入连接列的视图。例如;

dbo.View1 INNER JOIN
dbo.table2 ON dbo.View1.combinedcode = dbo.table2.code

在“View1”内部有一列是这样组成的;

dbo.tableA.details + dbo.tableB.code AS combinedcode

在此列上执行连接非常慢。然而,实际的“View1”运行得非常快。连接性能不佳,任何表或视图中的行数都不多。有谁知道这可能是为什么?

感谢您的任何见解!

4

4 回答 4

3

由于 上没有索引combinedcode,因此JOIN很可能会导致视图的完整“表扫描”以计算每一行的代码。

如果您想加快速度,请尝试将视图制作为带有索引的索引视图combinedcode帮助连接。

另一种选择,取决于您的 SQL 服务器版本,是(正如 Parado 的回答)为连接创建一个临时表,尽管它通常性能较低,至少对于单次查询而言。

于 2013-07-23T11:14:11.663 回答
1

试试这个方法:

select *
into #TemTap
from View1
/*where conditions on view1*/

之后你index可以#TemTap.combinedcode创建

dbo.#TemTap as View1 INNER JOIN dbo.table2 ON dbo.View1.combinedcode =
dbo.table2.code

它经常对我有用。

于 2013-07-23T11:10:07.967 回答
0

原因是因为优化器没有连接列的信息,所以无法选择合理的连接路径。如果您查看执行计划,我的猜测是该连接使用的是“嵌套循环”连接。(我很想在上面加上“可怕的”。)

您可以通过在table2(code). 优化器应该决定使用这个索引,绕过糟糕的连接优化。

您还可以使用查询提示来强制使用“散列连接”或“合并连接”。我发现自己更频繁地为复杂查询执行此操作,其中数据更改可能会影响查询计划。(当一个查询已经花费了 2 分钟一年后决定花费几个小时、填充临时数据库并在空间不足时终止时,此类提示就会出现。)您可以通过添加OPTION (merge join, hash join)到查询的末尾来做到这一点。您还可以在on子句中显式选择连接类型。

最后,将中间结果存储在临时表中(如 Parado 建议的那样)应该为优化器提供足够的信息来选择最佳连接算法。

于 2013-07-23T11:17:04.503 回答
0

不建议使用 SQL 函数。在这里,您在 where 条件下使用连接(间接但可以)。因此它对每一行执行连接,然后将其与其他表进行比较。

现在解决方案将尝试使用中间表而不是这个视图来保存连接值。

如果不可能尝试使用索引视图,我知道这是一项艰巨的任务。我宁愿创建中间表。

请参阅索引视图的链接 http://msdn.microsoft.com/en-us/library/ms191432.aspx#Restrictions

于 2013-07-23T12:59:07.160 回答