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.indexes
在filter_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 子句,因为那被视为代码,您只能访问数据。
确实 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.
有什么方法可以调查我在创建过滤索引期间没有用作值的内容吗?我看过索引创建脚本,但仍然没有价值。
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.indexes
在filter_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 子句,因为那被视为代码,您只能访问数据。
确实 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.