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

Nob*_*ife 18 sql sql-server indexed view

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

关于连接的问题,其中一列一侧为空

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

我似乎在这里撞墙,因为我无法将我的左连接转换为内连接,因为这将排除任何连接列上具有空值的所有记录.我的问题是:

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

我昨天刚刚完成了一个SQL Server课程,所以不知道如何继续.非常感谢任何评论.干杯.

coc*_*lla 13

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

创建两个物化视图(mA和mAB)(编辑:mA可能只是基表).mA缺少A和B之间的连接(因此包含所有A的周期[因此包含那些在B中没有匹配的记录]).mAB在A和B之间连接(因此只包含A与B的[并因此排除那些没有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;
Run Code Online (Sandbox Code Playgroud)

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

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


Mag*_*nus 7

有一个"解决办法" 这里涉及检查NULL在连接并具有NULL 在表中表示值

NULL值

INSERT INTO Father (Father_id, Father_name) values(-255,'No father')
Run Code Online (Sandbox Code Playgroud)

加入

JOIN [dbo].[son] s on isnull(s.father_id, -255) = f.father_id
Run Code Online (Sandbox Code Playgroud)

  • @Damien,@ gbn:只有我这个"解决方法"看起来很糟糕吗?其他具有`SELECT COUNT(*)FROM rightTable`的查询会发生什么?您将不得不更改它们以更正它们在解决方法后给出的错误(1)? (15认同)
  • @ypercube你的权利,它是可怕的,而不是一个真正的解决方法.但这是实现你想要的唯一途径.更好的解决方案可能是索引基础表并跳过索引视图. (2认同)
  • @Damien,就像古老的成语一样:乞丐不能选择 (2认同)

小智 6

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

Select * 
into <REAL_TABLE>
From <VIEW>

create CLUSTERED index <INDEX_THE_FIELD> on <REAL_TABLE>(<THE_FIELD>)
Run Code Online (Sandbox Code Playgroud)

但是,如果数据不是每隔几秒更新一次,这只是一个值得注意的方法.

  • 这是一个很好的解决方案.无需每次都更新整个表.我们可以编写触发器并仅更新已更改的行. (3认同)