强制受信任的外键 SQL Server 允许在视图中加入剔除

Posted

技术标签:

【中文标题】强制受信任的外键 SQL Server 允许在视图中加入剔除【英文标题】:Force trusted foreign key SQL Server to allow join culling in view 【发布时间】:2017-08-06 13:34:11 【问题描述】:

我正在尝试为其维度创建一个星型模式视图。

例如。

如果视图是

Select  
    _fact.A, _Dim.B
from 
    _fact
inner join 
    _dim on _Fact.dim_sk = _dim.Dim_sk

我查询

Select _Fact.A 
from _view

它将忽略 _dim 中的连接。

这样做的一种方法是创建维度的可信外键。 然而,这意味着我必须创建并启用检查约束,这会减慢我的插入速度。

https://www.brentozar.com/archive/2015/05/do-foreign-keys-matter-for-insert-speed/

    有没有更好的方法来允许在视图中进行连接剔除?

    有没有办法强制 SQL Server 将外键标记为可信?

例如类似于

的东西
update sys.foreign_keys
set is_not_trusted = 0

【问题讨论】:

您是否检查了计划以确保它实际上正在执行连接?另外,如果这是一个问题,你为什么不直接从表中选择?我认为问题中缺少信息/ 您好,该视图用于 BI 可视化工具,例如 Tableau/PowerBI。似乎有很多连接(100+)它使画面变得爬行。 【参考方案1】:

首先,您可能确实需要在架构中强制执行 FK。如果需要,您可以禁用它们并在 ETL 结束时检查它们,它们很有用。

但是,在某种程度上,您希望将 FK 保留为 NOCHECK 以提高性能。

所以另一种选择是使用LEFT JOIN,然后只要DIM表在join列上有唯一索引,SQL就知道join不能改变结果的基数,就会消除join如果不引用维度列。例如:

    use tempdb

    go

    drop table if exists _fact 
    drop table if exists _dim
    go
    create table _dim(Dim_sk int primary key, B int)

    create table _fact( A int, dim_sk int references _dim)

    go

    create or alter view _view
    as
    Select  
        _fact.A, _Dim.B
    from 
        _fact
    left join 
        _dim on _Fact.dim_sk = _dim.Dim_sk

    go
    set statistics io on
    go
    Select A 
    from _view
    go
    set statistics io off

输出

Table '_fact'. Scan count 1, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

【讨论】:

感谢 David,我可以确认将其更改为 PK 或唯一索引上的左连接确实会剔除连接,这是一种更好的做事方式,然后为我的需要创建 FK 约束。 请注意,在 DW 中包含 FK 绝对是最佳实践,因为它们向用户提供元数据。问题是是否强制执行。 @DavidBrowne-Microsoft 我有点不同意 FK 是一种最佳实践。不要忘记,Microsoft 的主要 DW 平台 - SQL Server 并行数据仓库和 Azure SQL 数据仓库 - 不支持它们。 PDW 和 SQL DW 不支持非强制 FK 是技术限制,而不是最佳实践声明。不可否认,强制 FK 很有用,但对于非常大的数据库可能不值得。

以上是关于强制受信任的外键 SQL Server 允许在视图中加入剔除的主要内容,如果未能解决你的问题,请参考以下文章

请问SQL server 中的主键和外键的作用

Sql Server 主键 外键约束

通过表和其他表执行搜索与 SQL Server 中的外键连接的内容以及如何对数据进行排序 [关闭]

用户“sa”登录失败。用户未与受信任的 SQL Server 连接关联。 (Microsoft SQL Server,错误:18452)在 sql 2008 中

不允许 SQL Server 约束子查询

sql。两个间的外键约束和插入数据问题