我有一个需要加入连接列的视图。例如;
dbo.View1 INNER JOIN
dbo.table2 ON dbo.View1.combinedcode = dbo.table2.code
在“View1”中,有一个列如此组成;
dbo.tableA.details + dbo.tableB.code AS combinedcode
在此列上执行连接非常慢。然而,实际的'View1'运行得非常快。连接带来的性能很差,任何表或视图中都没有很多行。有谁知道为什么会这样?
感谢您的任何见解!
答案 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