SQL Server - 使用当前的GetDate过滤器创建模式绑定索引视图

时间:2011-10-07 11:12:07

标签: sql-server sql-server-2008 indexed-view

我想创建以下索引视图:

CREATE VIEW [Cic].[vwMarker] WITH SCHEMABINDING 
    AS

    Select
        SubId,
        marker.EquipmentID,
        marker.ReadTime,
        marker.CdsLotOpside,
        marker.CdsLotBackside,
        marker.CdteLotOpside,
        marker.CdTeLotBackside
    From dbo.Marker 
    Where dbo.Marker.ReadTime >= Convert(dateTime,'10/5/2011',120)
GO

CREATE UNIQUE CLUSTERED INDEX IX_vwMarker_ReadTime_EquipmentID 
       ON Cic.vwMarker (ReadTime, EquipmentID);

这很好用。但是,我真正想要做的是在此视图中仅包含两天或更新的行,从查询视图的当前日期/时间开始。我找不到这样做的方法,因为我不能在Where谓词中使用GetDate(),因为它是非确定性的。换句话说,我想做这样的事情,但不能:

Where dbo.Marker.ReadTime >= Convert(dateTime,DateAdd(dd,-2,GetDate()) ,120)

有解决方法吗?

1 个答案:

答案 0 :(得分:13)

AFAIK您不会绕过SCHEMABINDING要求的确定性函数。您将始终收到错误

  

函数'getdate'产生不确定的结果。使用确定性系统函数,或修改用户定义函数以返回确定性结果。

如果Marker只是一个表,我不确定索引视图是否会比(ReadTime, EquipmentID)基础表上具有相同聚簇索引的表的普通视图具有任何性能优势

但是,如果“Marker”本身就是一个复合体,例如VIEW,或者如果您不想更改Marker表上的Clustered Index,那么您可能会考虑这样的事情:

  • 创建没有ReadDate过滤器(vwMarker)
  • 的架构绑定视图
  • 在未过滤的视图上创建索引视图
  • 创建第二个非架构绑定视图vwMarkerRecent等,它会添加非确定性GetDate过滤器。

Sql Fiddle example here

即。类似的东西:

CREATE VIEW [Cic].[vwMarker] WITH SCHEMABINDING 
    AS
    Select
        SubId,
        marker.EquipmentID,
        marker.ReadTime,
        marker.CdsLotOpside,
        marker.CdsLotBackside,
        marker.CdteLotOpside,
        marker.CdTeLotBackside
    From dbo.Marker 
    -- Add only Deterministic where filters here
GO

CREATE UNIQUE CLUSTERED INDEX IX_vwMarker ON Cic.vwMarker (ReadTime, EquipmentID)
GO    


CREATE VIEW [Cic].[vwRecentMarker] -- Not Schema Bound
    AS
        Select
            vm.SubId,
            vm.EquipmentID,
            vm.ReadTime,
            vm.CdsLotOpside,
            vm.CdsLotBackside,
            vm.CdteLotOpside,
            vm.CdTeLotBackside
        From cic.vwMarker vm
        Where vm.ReadTime >= Convert(dateTime,DateAdd(dd,-2,GetDate()) ,120)
    GO