替换视图中的左联接以便我可以拥有索引视图



我对数据库中的表进行了规范化,为了对其进行非规范化,我用两个表创建了一个视图。当我试图在视图上创建聚集索引时,它不允许我这样做,因为视图是用左外部联接创建的。我使用了左联接,因为我希望null值显示在结果视图中,就像前面文章中建议的那样。

关于一列一侧为空的联接问题

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

我在这里似乎遇到了麻烦,因为我无法将左联接转换为内部联接,因为这将排除任何联接列上所有具有null值的记录。我的问题是:

  1. 为什么不允许对外部联接或自联接进行索引
  2. 这种未编入索引的视图是否有任何性能方面的影响
  3. 有人知道这个问题的解决方法吗

我昨天刚完成SQL Server课程,所以不知道如何继续。如有意见,不胜感激。干杯

这里有一个替代方案。你想要一个不包含B的a的物化视图。这不是直接可用的。。。因此,具体化两种观点。所有A中的一个,以及仅有的一个A和B。然后,只取A而不取B。这可以有效地完成:

创建两个具体化视图(mA和mAB)(编辑:mA可能只是基表)。mA缺少A和B之间的连接(因此包含所有A的周期[因此包含B中没有匹配项的那些记录])。mAB在A和B之间连接(因此只包含有B的A[因此排除了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在处理现有数据方面比处理不存在的数据要好得多。通过具体化两个来源,您可以获得一些引人注目的基于集合的选项。你必须自己权衡这些观点的成本与收益。

这里有一个"变通方法",涉及在联接中检查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

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

Select * 
into <REAL_TABLE>
From <VIEW>
create CLUSTERED index <INDEX_THE_FIELD> on <REAL_TABLE>(<THE_FIELD>)

但是,如果数据不是每隔几秒钟更新一次,那么这只是一种值得注意的方法。

从逻辑上讲,您正在进行两个独立的查询。'"左联接B"只是"(A联接B)联合A"的简写

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

第二个查询只是表A,其中任何联接列都为null。制作一个与第一个查询产生相同输出列的视图,并用null填充它们。

将两个结果合并后再返回。不需要变通方法。

我将研究1的答案,但现在:

[2] 。该视图的性能不会比udnerlaying表上的等效查询差多少。所有通常的建议都适用于具有覆盖索引,最好是连接列上的索引,等等。

[3] 。没有真正的解决办法。一旦深入研究,对索引视图的大多数限制都是有充分理由的。

一般来说,我只会创建视图,不再执行任何操作,除非出现特定的性能问题。

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

相关内容

  • 没有找到相关文章

最新更新