加入连接列性能

时间:2013-07-23 11:05:42

标签: sql sql-server tsql

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

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

在“View1”中,有一个列如此组成;

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

在此列上执行连接非常慢。然而,实际的'View1'运行得非常快。连接带来的性能很差,任何表或视图中都没有很多行。有谁知道为什么会这样?

感谢您的任何见解!

4 个答案:

答案 0 :(得分:3)

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

如果您想加快速度,请尝试将视图转换为combinedcode,并在{{1}}上添加索引以帮助加入。

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

答案 1 :(得分: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

它通常适合我。

答案 2 :(得分:0)

原因是因为优化器没有关于连接列的信息,因此无法选择合理的连接路径。我猜,如果你看一下执行计划,那就是连接是使用“嵌套循环”连接。 (我很想加上“可怕的”。)

您可以通过在table2(code)上添加索引来解决此问题。优化器应决定使用此索引,绕过错误的连接优化。

您还可以使用查询提示强制使用“散列连接”或“合并连接”。我发现自己更频繁地为复杂查询执行此操作,其中数据更改可能会影响查询计划。 (当一年中花费2分钟的查询决定花费数小时,填充临时数据库,并在空间不足时死亡时,此类提示会进入。)您可以通过向OPTION (merge join, hash join)添加on来实现此目的。查询结束。您还可以在{{1}}子句中明确选择连接类型。

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

答案 3 :(得分:0)

使用SQL函数是不建议使用条件的地方。在这里你使用concatenate where where condition(间接但是是)。所以它正在为每一行执行连接,然后将它与其他表进行比较。

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

如果不可能尝试使用索引视图,我知道它是一个任务的地狱。 我宁愿创建中间表。

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