在 Sql Server 2008 中索引视图是不是实际上复制了原始数据?

Posted

技术标签:

【中文标题】在 Sql Server 2008 中索引视图是不是实际上复制了原始数据?【英文标题】:Does Indexing a View in Sql Server 2008 actually duplicate the original data?在 Sql Server 2008 中索引视图是否实际上复制了原始数据? 【发布时间】:2011-04-09 00:39:04 【问题描述】:

如果我创建一个索引视图(在 Sql Server 2008 中),这是否意味着我将所有需要的数据从源表复制到一个单独的新表中?还是只保存了一些微小的指针/索引来表示这个视图?

【问题讨论】:

【参考方案1】:

在视图上创建唯一聚集索引时,结果集将存储在数据库中,就像存储具有聚集索引的表一样。

当对基表中的数据进行修改时,数据修改会反映在索引视图中存储的数据中

~来自msdn

【讨论】:

所以答案是......'是的 - 数据是重复的'...... ??【参考方案2】:

是的,数据已复制。 Oracle 等其他数据库平台将此称为Materialized View,因为数据将materialize 转化为物理形式。

【讨论】:

【参考方案3】:

是的,数据是单独复制和存储的,因此如果您修改基础表,您的索引视图将自动更新。 This causes a lot of lock contention。此外,索引视图可能会变得比基础表大并适得其反。

【讨论】:

【参考方案4】:

您可以使用(未​​记录但被广泛使用的)DBCC PAGE 命令准确查看存储的内容。下面将创建一个索引视图并打印第一个数据页的内容。

SET NOCOUNT ON
IF OBJECT_ID('tempdb..#dbcc_ind') IS NOT NULL
    TRUNCATE TABLE #dbcc_ind
ELSE
    CREATE TABLE #dbcc_ind
    (PageFID  TINYINT, 
    PagePID INT,   
    IAMFID   TINYINT, 
    IAMPID  INT, 
    ObjectID  INT,
    IndexID  TINYINT,
    PartitionNumber TINYINT,
    PartitionID BIGINT,
    iam_chain_type  VARCHAR(30),    
    PageType  TINYINT, 
    IndexLevel  TINYINT,
    NextPageFID  TINYINT,
    NextPagePID  INT,
    PrevPageFID  TINYINT,
    PrevPagePID INT, 
    PRIMARY KEY (PageFID, PagePID));

IF OBJECT_ID('dbo.vtest') IS NULL
CREATE TABLE dbo.vtest (
i INT IDENTITY(1,1)  NOT NULL PRIMARY KEY,
c1 CHAR(500) NOT NULL DEFAULT REPLICATE('x',500), 
c2 CHAR(500) NOT NULL DEFAULT REPLICATE('y',500) 
)
GO

INSERT INTO dbo.vtest DEFAULT VALUES
GO 10

IF OBJECT_ID('dbo.ixViewTest') IS NULL
BEGIN
EXEC('CREATE VIEW dbo.ixViewTest
WITH SCHEMABINDING
AS
SELECT i,c1,c2
FROM dbo.vtest;')
EXEC('CREATE UNIQUE CLUSTERED INDEX [cix] ON [dbo].[ixViewTest] ([i] ASC)')
END
GO


DECLARE @command VARCHAR(1000)
SET @command = 'DBCC IND(' + QUOTENAME(DB_NAME()) + ', ixViewTest,1) WITH NO_INFOMSGS;'

INSERT INTO #dbcc_ind
    EXEC ( @command );


SELECT @command= 'DBCC PAGE (' + QUOTENAME(DB_NAME()) + ',' + CAST(PageFID AS VARCHAR(5)) + ',' + CAST(PagePID AS VARCHAR(10)) + ',1) ;'
FROM #dbcc_ind
WHERE PageType=1
 AND PrevPagePID=0


DBCC TRACEON(3604)
EXEC ( @command )
DBCC TRACEOFF(3604)

【讨论】:

以上是关于在 Sql Server 2008 中索引视图是不是实际上复制了原始数据?的主要内容,如果未能解决你的问题,请参考以下文章

了解 SQL Server 2008 R2 中索引视图中的列类型

在 SQL Server 2008 中将两个表合并到一个索引视图中

关于视图和索引 (SQL Server 2008 R2)

SQL Server 2008 R2 和索引视图中的执行计划

了解 SQL Server 2008 R2 中的索引视图更新和查询过程

SQL Server 索引最佳实践(SQL Server 2008)[关闭]