【发布时间】:2013-09-25 12:06:08
【问题描述】:
假设我有一个这样的表架构:
Partners表
ID Name
1 Test
Partners_Codes表
Partner_ID Code
1 'Test_Code'
我在Partners_Codes 中的Partner_ID 上也有唯一的聚集索引:
create unique clustered index IX_Partners_Codes on Partners_Codes (Partner_ID);
现在,当我这样查询时:
select
P.ID, P.Name
from dbo.Partners as P
left outer join dbo.Partners_Codes as PC on PC.Partner_ID = P.ID;
SQL Server 优化器足够智能,可以查看 Partners_Codes 上的索引,而根本不查询 Partners_Codes,这对性能很有好处。
现在假设我必须在Partners_Codes 中添加一个Active 列,这样每个Partner 可以有很多代码,但其中只有一个代码可以是Active。
Partners_Codes2表
Partner_ID Code Active
1 'Test_Code' 1
1 'Test_Code_old1' 0
1 'Test_Code_old2' 0
我尝试了 2 种方法 - 在 Active = 1 上使用过滤索引或在此视图上创建视图和唯一索引:
create table Partners_Codes2 (Partner_ID int, Code nvarchar(128), Active bit);
create view vw_Partners_Codes2
with schemabinding
as
select
Partner_ID, Code
from dbo.Partners_Codes2
where Active = 1;
create unique clustered index IX_vw_Partners_Codes2 on vw_Partners_Codes2 (Partner_ID);
create table Partners_Codes3 (Partner_ID int, Code nvarchar(128), Active bit);
create unique clustered index IX_Partners_Codes31 on Partners_Codes3 (Partner_ID, Code);
create unique nonclustered index IX_Partners_Codes32 on Partners_Codes3 (Partner_ID) include(Code, Active) where (Active = 1);
但是对于这两种方法,SQL Server 优化器将查询Partners_Codes 表,即使它应该知道表中只有一行或零行并且我没有从表中获取任何数据。
我的实际架构有点复杂,我不想将数据拆分为多个表。问题是 - 是否可以创建过滤索引或索引视图,以便优化器在所示情况下使用它?
相关链接:
【问题讨论】:
-
您使用的是企业版和/或您在查询视图时是否指定了
NOEXPAND?要考虑索引,您至少需要其中一项为真。 -
@Damien_The_Unbeliever 是的,企业版
-
@Damien_The_Unbeliever 添加了答案,谢谢,您帮助我找到了正确的方向
标签: sql sql-server database-design sql-server-2008-r2 query-optimization