SQL Server索引视图

11

我试图在SQL Server中创建一个索引视图,想知道是否需要为视图列建立索引。

我之所以问这个问题,是因为该视图由已经有列索引的表组成。

如果TABLE1已经将列FOO作为非聚集索引进行了索引,那么我是否需要为新创建的视图添加列FOO的索引,以便SQL Server使用索引?

还是说当搜索视图时,SQL Server会知道使用TABLE1中的索引?

该视图如下:

CREATE VIEW [dbo].[v_eventActivity] 
WITH SCHEMABINDING 
AS 
  SELECT ea.id, 
         e.eventID, 
         e.name, 
         ea.userID, 
         ea.activityTypeID, 
         ea.timeStamp, 
         ea.visitDuration 
  FROM   dbo.table1 e, 
         dbo.table2 ea 
  WHERE  e.eventID = ea.eventID 

我要在所有这些列上一起进行搜索。

如前所述,table1和table2中的所有这些列已经建立了索引。


我以为我知道这个问题的答案,但在写作时发现实际上我并不知道。好问题!最好的方法可能是尝试并查看结果。此外,您应该指定SS版本。 - JNK
通常,索引视图并不代表整个表,因此通常表示特定列上的索引是没有意义的。您已经创建了该视图吗?您可以分享表结构、您所讨论的索引以及视图的定义(包括其索引)吗? - Aaron Bertrand
我确实尝试过。查询执行计划表明它确实使用了原始表的索引。但我只是想确认一下。 - KDV
执行计划会知道的 ;) - JNK
@JNK被难住了?!?我不信。 - Yuck
1
@Yuck 好的,我开始回答了,但是意识到优化器可以机会主义地使用索引视图索引,所以它可能也可以用于表,但后来我意识到我不确定,所以希望 Aaron 或其他聪明人能回答。 - JNK
2个回答

7
视图将简单地利用表索引,除非提供NOEXPAND提示(文档在这里)。
您可以按照以下方式进行测试:
CREATE TABLE [test].[TestTable] (
    id INT IDENTITY PRIMARY KEY,
    foo INT
)

CREATE NONCLUSTERED INDEX ixFoo
ON [test].[TestTable] (foo)

CREATE VIEW [test].[TestTableView] WITH SCHEMABINDING
AS
    SELECT
        t.id,
        t.foo
    FROM [test].[TestTable] t
GO

CREATE UNIQUE CLUSTERED INDEX ixFooId
ON [test].[TestTableView] (id)

CREATE NONCLUSTERED INDEX ixFooView
ON [test].[TestTableView] (foo)

以下是三个不同查询的执行计划:

SELECT
    t.[id],
    t.[foo]
FROM [test].[TestTable] t
ORDER BY t.[foo]

The table query execution plan

SELECT
    v.[id],
    v.[foo]
FROM [test].[TestTableView] v
ORDER BY v.[foo]

The view with no hint

SELECT
    v.[id],
    v.[foo]
FROM [test].[TestTableView] v WITH (NOEXPAND)
ORDER BY v.[foo]

The view with the NOEXPAND hint


5
SQL Server 中的索引视图与其他地方所说的物化视图基本相同。如果您的视图使用了基表定义的索引,则在视图上选择将使用该索引,但这并不是索引视图的主要作用。
如果您经常使用该视图且性能很重要,可以选择放弃更多磁盘空间(和 CPU 时间),并在该视图上创建唯一聚集索引,从而使视图查询更快,因为 SQL Server 不必返回到基表或表,并且可以从视图索引中获取所有需要的内容。
请参见此处

1
如果它已经是一个索引视图,那么您无法在该视图上添加唯一的聚簇索引。这就是索引视图的定义(除非已经存在唯一的聚簇索引,否则不能在视图上创建非唯一或非聚簇索引)。 - Aaron Bertrand
1
@AaronBertrand:视图必须没有先前的索引,我并不意味着它有!表可能有索引。 - Mithrandir
1
我理解你的描述是希望在索引视图中添加一个唯一聚集索引。 - Aaron Bertrand
抱歉,这是一个误解,实际上你需要做的是,使用没有索引的干净视图并定义一个单一的聚集唯一索引!这样就可以创建一个索引视图了!在Oracle中经常这样做,至少我曾经在某些情况下这样做过。 - Mithrandir
是的,我相信我们都知道索引视图的工作原理。我只是想指出你的描述可能会误导和混淆一些人,所以想澄清一下,你不能向索引视图添加聚集索引。 - Aaron Bertrand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接