要替换什么左边连接在一个视图中,所以我可以有一个索引视图?

时间:2011-06-25 09:21:16

标签: sql sql-server view indexed

我在数据库中对表进行了规范化并对其进行了非规范化,我从两个表中创建了一个视图。当我尝试在视图上创建聚簇索引时,它不会让我,因为视图是使用左外连接创建的。我使用左连接,因为我希望在结果视图中显示空值,就像在之前的帖子中建议的那样。

Question on join where one column one side is null

表结构和关系与上面链接中描述的非常类似。

我似乎碰到了一堵墙,因为我无法将左连接转换为内部连接,因为这将排除任何连接列上具有空值的所有记录。我的问题是:

  1. 为什么外部或自联接不允许编制索引?
  2. 这种未编入索引的视图是否有性能点击?
  3. 任何人都知道解决这个问题的方法吗?
  4. 我昨天刚刚完成了一个SQL Server课程,所以不知道如何继续。非常感谢任何评论。欢呼声。

5 个答案:

答案 0 :(得分:13)

这是另一种选择。你想要一个不包含B的A的物化视图。这不是直接可用的...所以相反,实现了两个视图。 A&A中的一个,也是B&B中唯一一个A&#39。然后,通过取A除了B,只得到A没有B。这可以有效地完成:

创建两个物化视图(mA和mAB)(编辑:mA可能只是基表)。 mA缺少A和B之间的连接(因此包含所有A&#39周期[因此包含那些没有B中匹配的记录])。 mAB连接在A和B之间(因此仅包含A' s [并因此排除那些没有B中匹配的记录]。)

要获得B中没有匹配项的所有A,请屏蔽匹配的内容:

with ids as (
  select matchId from mA with (index (pk_matchid), noexpand)
  except
  select matchId from mAB with (index (pk_matchid), noexpand)
)
select * from mA a join ids b on a.matchId = b.matchId;

这应该产生针对两个聚簇索引的左反半连接以获取ID,并且聚集索引寻求从您正在寻找的mA中获取数据。

基本上,您遇到的基本规则是,SQL处理IS中的数据要比ISN&T的数据好得多。通过实现两个来源,您可以获得一些引人注目的基于集合的选项。你必须自己权衡这些观点的成本与这些收益。

答案 1 :(得分:7)

有一个“变通方法”here,其中涉及检查联接中的NULL并在表格中显示NULL个代表值

NULL值

INSERT INTO Father (Father_id, Father_name) values(-255,'No father')

加入

JOIN [dbo].[son] s on isnull(s.father_id, -255) = f.father_id

答案 2 :(得分:6)

我认为没有一个好的解决方法。你可以做的是从视图创建一个真实的表并在其上设置索引。这可以通过在更新数据时定期调用的存储过程来完成。

Select * 
into <REAL_TABLE>
From <VIEW>

create CLUSTERED index <INDEX_THE_FIELD> on <REAL_TABLE>(<THE_FIELD>)

但如果每隔几秒钟没有更新数据,这只是一个值得注意的方法。

答案 3 :(得分:1)

逻辑上,您正在进行两个单独的查询。 “LEFT JOIN B”只是'(A JOIN B)UNION A'的缩写

第一个查询是表A连接到表B的内部。这得到一个索引视图,因为这是完成所有繁重工作的地方。

第二个查询只是表A,其中任何连接列都为空。创建一个与第一个查询生成相同输出列的视图,并用空值填充它们。

在返回之前将两个结果合并。无需解决方法。

答案 4 :(得分:0)

我会回答1,但现在:

[2]。与udnerlying表上的等效查询相比,该视图的性能不会更高也不会更低。所有通常的建议都适用于覆盖索引,最好是连接列的索引等等。

[3]。没有真正的解决方法。一旦你深入了解索引视图的大部分限制都存在很好的理由。

除非出现特定的性能问题,否则我只会创建一般视图,不会再创建视图。

一旦我在自己的脑海中重建它,我会尝试为1添加一个答案。