SQL Server 2008 R2 筛选索引

SQL Server 2008 R2 filtered index

有什么方法可以调查我在创建过滤索引期间没有用作值的内容吗?我看过索引创建脚本,但仍然没有价值。

create nonclustered index IX1 where status=0

我正在下面的查询中查找状态列和 0 值

根据评论,SQL Management Studio 可以编写过滤索引的脚本。只需右键单击您的索引并单击 Script Index as。但是,如果您想使用 SQL 查询它,您可以只 select 来自 sys.indexes table:

filter definition
 SELECT SCHEMA_NAME(t.schema_id) ,
       t.name ,
       i.name ,
       filter_definition
 FROM   sys.indexes i
       INNER JOIN sys.tables t ON t.object_id = i.object_id
 WHERE  i.type > 0
       AND t.is_ms_shipped = 0
       AND t.name <> 'sysdiagrams'
       AND ( is_primary_key = 0
            AND is_unique_constraint = 0
          )
       AND i.name = 'IX1'

内置系统目录视图sys.indexesfilter_definition列有过滤信息:

select
    o.name as [Table],
    i.name as [Index],
    i.filter_definition as [Filter]
from sys.objects o
inner join sys.indexes i on i.object_id = o.object_id
where i.name = 'IX1'

您很可能无法确认过滤索引 where 子句,因为那被视为代码,您只能访问数据。

https://dba.stackexchange.com/questions/55811/database-having-only-db-datareader-shows-invalid-properties-for-a-index

确实 db_datareader 无法直接确认筛选索引 where 子句 (sys.indexes.filter_definition),并且 SSMS 不会警告 db_datareader 编写索引定义脚本将不完整.

但是,db_datareader 可以使用一种解决方法来间接确认 filter_definition:在查询中指定索引提示,使用 where 子句来测试过滤索引的覆盖率.

MS-SQL 将抛出错误,如果您在查询 where 子句中指定的列或值未被过滤索引 where 子句 (sys.indexes.filter_definition) 覆盖。

这样一来,您至少可以验证要使用的查询 where 子句是否包含在过滤索引中。以这种方式验证后,您不需要在生产中使用索引提示。

例如,如果筛选索引是由 db_owner 创建的,如下所示:

CREATE UNIQUE INDEX UQ_ZipData_PrimaryPerZip
 ON dbo.ZipData (ZIP) WHERE IsPrimaryCity = 1

那么作为 db_datareader,我可以确认这个查询有效,所以我已经确认 IsPrimaryCity = 1 被索引覆盖:

SELECT COUNT(*) AS Num
  FROM dbo.ZipData WITH (INDEX (NCI_ZipData_Zip))
  WHERE IsPrimaryCity = 1

同样作为 db_datareader,我可以确认此查询失败,因此我已确认 IsPrimaryCity = 0 未被索引覆盖:

SELECT COUNT(*) AS Num
  FROM dbo.ZipData WITH (INDEX (NCI_ZipData_Zip))
  WHERE IsPrimaryCity = 0

MS-SQL返回的错误信息是:

Msg 8622, Level 16, State 1, Line 1
Query processor could not produce a query plan because of the hints defined in this query. Resubmit the query without specifying any hints and without using SET FORCEPLAN.