2009-11-14 183 views
1

我需要一些指针来说明如何调试以下问题。为什么SQL索引视图始终使用聚簇索引

环境:SQL Server 2005 Enterprise。

我有一个包含聚集索引和多个非唯一,非聚集索引的索引视图。但是,当我执行查询时,SQL服务器始终执行Clustered索引扫描,而不是索引查找在我的密钥上。

这是一个简化版本。

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' 

,并期待在执行计划时,我看到a.Col1 SQL服务器运行群集索引扫描,而不是执行对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上的索引查找。我尝试交换查询的顺序(先运行b,然后运行)产生相同的百分比。

  • 这个小小的实验证实,如果sql使用索引查找,它将比集群索引扫描更快。
  • 第二我虽然如果我不包含“WITH(NOEXPAND)”,那么SQL服务器将不会使用索引视图上的索引。 (也许我应该开始创建索引视图的确切步骤的另一个问题)。
+0

如果查询分析器来,一个聚集索引扫描比寻求更快的conlusion,它会做一个扫描 - 即使是索引。这可能与视图中的行数,索引的选择性以及其他几个元素有关。仅仅因为有索引扫描并不意味着索引不“工作” - 对于那个查询,它可能更容易做一次索引扫描。 – 2009-11-14 08:34:56

+0

marc_s - 查看我的更新,我并排运行这两个查询,并向我展示如果使用sql索引查找它将比集群索引扫描快得多。 – DHornpout 2009-11-16 20:31:48

回答

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 @[email protected]+1 
end 

执行您的查询

SELECT Col1中,Col2中,COL3 FROM MyIndexedView WITH(NOEXPAND)WHERE col2的= '等等'

示出了一个索引查找上IX2

但如果停用该索引 ALTER INDEX [IX2] ON [ DBO]。[MyIndexedView] DISABLE

并重新运行,我看到MyIndexedView.IX

聚集索引扫描
+0

我很欣赏你试图重现这个问题。我确实验证了“使用索引”是在col2列上检查的。我确实删除并重新创建索引(不知道它是否与重建相同)。 – DHornpout 2009-11-16 20:30:38

相关问题