我需要一些关于如何调试以下问题的指针。
环境:SQL Server 2005 Enterprise。
我有一个索引视图,其中包含聚簇索引和多个非唯一的非聚集索引。但是,当我执行查询时,SQL服务器始终执行Clustered index scan而不是我的密钥上的索引搜索。
这是一个简化版本。
CREATE VIEW MyIndexedView WITH SCHEMABINDING
SELECT a.Col1, b.Col2, c.Col3, d.Col4
FROM a JOIN b on a.id = b.id
JOIN c on a.id = c.id
JION d on c.id = d.id
Col1上有一个聚簇索引,Col2,Col3上有非唯一的非聚簇索引。
当我运行以下查询时
SELECT a.Col1, b.Col2, c.Col3 FROM MyIndexedView WITH(NOEXPAND) WHERE b.Col2='blah'
并查看执行计划,我看到SQL Server在a.Col1上运行Clustered index scan而不是在Col2上执行索引查找。
我尝试重新创建视图和索引。
更新: 我做了一些额外的测试,并在查询分析器中并排运行这两个查询。
a) SELECT a.Col1, b.Col2, c.Col3
FROM MyIndexedView WITH(NOEXPAND) WHERE b.Col2='blah'
b) SELECT a.Col1, b.Col2, c.Col3
FROM MyIndexedView WHERE b.Col2 = 'blah'
查询'a'将占用95%的时间并使用群集索引扫描。查询'b'只占用5%的时间并在col2上使用Index Seek。我尝试交换查询顺序(先运行b和后运行)产生相同的百分比。
答案 0 :(得分:4)
我复制了你的样本,并在Col2上找到索引的预期结果。我能够让它进行聚簇索引扫描的唯一方法是我是否禁用了索引。因此,首先尝试在Col2上重建索引以确保它实际启用(或检查索引属性中的“使用索引”复选框 - 选项)。
以下是我用来创建表格的视图,视图和索引
CREATE TABLE [dbo].[a](
[id] [int] IDENTITY(1,1) NOT NULL,
[Col1] [varchar](100) NOT NULL,
CONSTRAINT [PK_a] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[b](
[id] [int] IDENTITY(1,1) NOT NULL,
[Col2] [varchar](100) NOT NULL,
CONSTRAINT [PK_b] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[c](
[id] [int] IDENTITY(1,1) NOT NULL,
[Col3] [varchar](100) NOT NULL,
CONSTRAINT [PK_c] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[d](
[id] [int] IDENTITY(1,1) NOT NULL,
[Col4] [varchar](100) NOT NULL,
CONSTRAINT [PK_d] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE VIEW [dbo].[MyIndexedView] WITH SCHEMABINDING
AS
SELECT a.Col1, b.Col2, c.Col3, d.Col4
FROM dbo.a JOIN dbo.b on a.id = b.id
JOIN dbo.c on a.id = c.id
JOIN dbo.d on c.id = d.id
GO
/****** Object: Index [IX] Script Date: 11/13/2009 21:50:01 ******/
CREATE UNIQUE CLUSTERED INDEX [IX] ON [dbo].[MyIndexedView]
(
[Col1] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/****** Object: Index [IX2] Script Date: 11/13/2009 21:50:39 ******/
CREATE NONCLUSTERED INDEX [IX2] ON [dbo].[MyIndexedView]
(
[Col2] ASC,
[Col3] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
我填写了这样的表:
declare @x int
SET @x = 0
while @x < 10
begin
INSERT INTO a (Col1 ) VALUES (newid())
INSERT INTO b (Col2 ) VALUES (newid())
INSERT INTO c (Col3 ) VALUES (newid())
INSERT INTO d (Col4 ) VALUES (newid())
SET @x=@x+1
end
执行查询
选择Col1,Col2,Col3来自MyIndexedView WITH(NOEXPAND)WHERE Col2 ='blah'
显示了对IX2的索引搜索
但如果我禁用该索引 ALTER INDEX [IX2] ON [dbo]。[MyIndexedView] DISABLE
然后重新运行,我在MyIndexedView.IX上看到聚集索引扫描
答案 1 :(得分:0)
您的视图中有多少条记录?
如果连接的结果很小,那么扫描聚簇索引比搜索另一个索引更具成本效益。