索引视图是否物理存储在数据库中以及使用索引视图的一些见解

前言

这个话题我本来是写在文章里没有写在随笔里的,不过赶脚不写在随笔里其他人就看不到了,因为小弟对视图的认识不深

希望写在随笔里让大家也讨论一下这个话题

小弟在文章的结尾会把我们公司系统使用索引视图的情况告诉大家,希望大家也把你们在系统中如何应用索引视图的在评论中分享一下

让小弟也学习一下,因为小弟对于索引视图的认识也是比较浅的


视图的种类

先来看一下SQLSERVER中视图的种类

1、标准视图

2、索引视图:加了索引,在SQL2000之后提供的新功能。在视图上创建索引后,该视图的结果集随机被具体化,并保存在数据库的物理存储中。

对索引视图创建的第一个索引必须是唯一聚集索引。创建了唯一聚集索引后,才可以创建其他非聚集索引。如果删除视图,该视图的索引也被删除,

若删除聚集索引,视图的所有非聚集索引和自动创建的统计信息也被删除。删除视图的聚集索引将删除存储的结果集,并且索引视图会变为标准视图

3、分区视图:在一台或多台服务器间水平连接一组成员表中的分区数据,使数据看起来像来自一个表。依据连接数据服务器的不同,

他又分为本地分区视图和分布式分区视图。分布式分区视图用于实现数据库服务器联合


验证

为了区分标准视图和索引视图,我们分别建立一张基本表、一个索引视图、一个标准视图,两个视图都是基于那个基本表

使用下面SQL语句建立测试环境

 1 USE [pratice]
 2 GO
 3
 4 --建表
 5 CREATE TABLE [dbo].[Users](
 6     [UserID] [int] IDENTITY(1,1) NOT NULL,
 7     [UserName] [nvarchar](50) NULL,
 8     [Age] [int] NULL,
 9     [Gender] [bit] NULL,
10     [CreateTime] [datetime] NULL
11 ) ON [PRIMARY]
12 GO
13
14 --插入数据
15 INSERT INTO [dbo].[Users] ( [UserName], [Age], [Gender], [CreateTime] )
16 SELECT '啊文',20,1,'2012-05-01' UNION ALL
17 SELECT '宝文',23,0,'2012-05-05' UNION ALL
18 SELECT '张武',38,1,'2012-05-04' UNION ALL
19 SELECT '刘星',32,0,'2012-05-08' UNION ALL
20 SELECT '小青',27,1,'2012-06-01' UNION ALL
21 SELECT '王八',16,1,'2012-07-08' UNION ALL
22 SELECT '臭屁',42,1,'2012-09-02'
23 GO
24
25 SELECT * FROM [dbo].[Users]
26 GO
27
28 --------------------------------------------------------
29 --创建索引视图
30 CREATE VIEW index_View_Users
31 WITH SCHEMABINDING
32 AS
33 SELECT UserID,UserName,Age,Gender,CreateTime FROM dbo.Users
34 GO
35
36 CREATE UNIQUE CLUSTERED INDEX CIX_View_Users ON index_View_Users(UserID)
37
38 SELECT * FROM index_View_Users
39
40
41 --创建标准视图
42 CREATE VIEW stand_View_Users
43 AS
44 SELECT UserID,UserName,Age,Gender,CreateTime FROM dbo.Users
45 GO
46
47 SELECT * FROM stand_View_Users
48
49
50 ---------------------------------------------------------

View Code

 1 CREATE TABLE [dbo].[DBCCResult](
 2     [PageFID] [nvarchar](200) NULL,
 3     [PagePID] [nvarchar](200) NULL,
 4     [IAMFID] [nvarchar](200) NULL,
 5     [IAMPID] [nvarchar](200) NULL,
 6     [ObjectID] [nvarchar](200) NULL,
 7     [IndexID] [nvarchar](200) NULL,
 8     [PartitionNumber] [nvarchar](200) NULL,
 9     [PartitionID] [nvarchar](200) NULL,
10     [iam_chain_type] [nvarchar](200) NULL,
11     [PageType] [nvarchar](200) NULL,
12     [IndexLevel] [nvarchar](200) NULL,
13     [NextPageFID] [nvarchar](200) NULL,
14     [NextPagePID] [nvarchar](200) NULL,
15     [PrevPageFID] [nvarchar](200) NULL,
16     [PrevPagePID] [nvarchar](200) NULL
17 ) ON [PRIMARY]
18 --TRUNCATE TABLE [dbo].[DBCCResult]
19 INSERT INTO DBCCResult EXEC ('DBCC IND(pratice,index_View_Users,-1) ')
20
21 SELECT * FROM [dbo].[DBCCResult] ORDER BY [PageType] DESC 

View Code

而标准视图是没有数据页存储视图数据的

1 INSERT INTO DBCCResult EXEC ('DBCC IND(pratice,stand_View_Users,-1) ')
2
3 SELECT * FROM [dbo].[DBCCResult] ORDER BY [PageType] DESC 

1 消息 5239,级别 16,状态 1,第 1 行
2 无法处理对象 ID 487672785 (对象 'stand_View_Users'),因为此 DBCC 命令不支持此类型的对象。
3
4 (0 行受影响)

我们看一下数据页37398里的内容,数据页里存储的内容跟基本表是一样的

  1 DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。
  2
  3 PAGE: (1:37398)
  4
  5
  6 BUFFER:
  7
  8
  9 BUF @0x03D91AFC
 10
 11 bpage = 0x1B706000                   bhash = 0x00000000                   bpageno = (1:37398)
 12 bdbid = 5                            breferences = 0                      bUse1 = 16885
 13 bstat = 0x1c0000b                    blog = 0x1212121b                    bnext = 0x00000000
 14
 15 PAGE HEADER:
 16
 17
 18 Page @0x1B706000
 19
 20 m_pageId = (1:37398)                 m_headerVersion = 1                  m_type = 1
 21 m_typeFlagBits = 0x0                 m_level = 0                          m_flagBits = 0x0
 22 m_objId (AllocUnitId.idObj) = 477    m_indexId (AllocUnitId.idInd) = 256
 23 Metadata: AllocUnitId = 72057594069188608
 24 Metadata: PartitionId = 72057594058309632                                 Metadata: IndexId = 1
 25 Metadata: ObjectId = 471672728       m_prevPage = (0:0)                   m_nextPage = (0:0)
 26 pminlen = 21                         m_slotCnt = 7                        m_freeCnt = 7858
 27 m_freeData = 320                     m_reservedCnt = 0                    m_lsn = (3043:16246:39)
 28 m_xactReserved = 0                   m_xdesId = (0:0)                     m_ghostRecCnt = 0
 29 m_tornBits = 0
 30
 31 Allocation Status
 32
 33 GAM (1:2) = ALLOCATED                SGAM (1:3) = ALLOCATED
 34 PFS (1:32352) = 0x60 MIXED_EXT ALLOCATED   0_PCT_FULL                     DIFF (1:6) = CHANGED
 35 ML (1:7) = NOT MIN_LOGGED
 36
 37 Slot 0 Offset 0x60 Length 32
 38
 39 Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
 40
 41 Memory Dump @0x0823C060
 42
 43 00000000:   30001500 01000000 14000000 01000000 †0...............
 44 00000010:   0044a000 000500e0 01002000 4a558765 †.D........ .JU.e
 45
 46 Slot 0 Column 0 Offset 0x4 Length 4
 47
 48 UserID = 1
 49
 50 Slot 0 Column 1 Offset 0x1c Length 4
 51
 52 UserName = 啊文
 53
 54 Slot 0 Column 2 Offset 0x8 Length 4
 55
 56 Age = 20
 57
 58 Slot 0 Column 3 Offset 0xc Length 1 (Bit position 0)
 59
 60 Gender = 1
 61
 62 Slot 0 Column 4 Offset 0xd Length 8
 63
 64 CreateTime = 05  1 2012 12:00AM
 65
 66 Slot 1 Offset 0x80 Length 32
 67
 68 Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
 69
 70 Memory Dump @0x0823C080
 71
 72 00000000:   30001500 02000000 17000000 00000000 †0...............
 73 00000010:   0048a000 000500e0 01002000 9d5b8765 †.H........ ..[.e
 74
 75 Slot 1 Column 0 Offset 0x4 Length 4
 76
 77 UserID = 2
 78
 79 Slot 1 Column 1 Offset 0x1c Length 4
 80
 81 UserName = 宝文
 82
 83 Slot 1 Column 2 Offset 0x8 Length 4
 84
 85 Age = 23
 86
 87 Slot 1 Column 3 Offset 0xc Length 1 (Bit position 0)
 88
 89 Gender = 0
 90
 91 Slot 1 Column 4 Offset 0xd Length 8
 92
 93 CreateTime = 05  5 2012 12:00AM
 94
 95 Slot 2 Offset 0xa0 Length 32
 96
 97 Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
 98
 99 Memory Dump @0x0823C0A0
100
101 00000000:   30001500 03000000 26000000 01000000 †0.......&.......
102 00000010:   0047a000 000500e0 01002000 205f666b †.G........ . _fk
103
104 Slot 2 Column 0 Offset 0x4 Length 4
105
106 UserID = 3
107
108 Slot 2 Column 1 Offset 0x1c Length 4
109
110 UserName = 张武
111
112 Slot 2 Column 2 Offset 0x8 Length 4
113
114 Age = 38
115
116 Slot 2 Column 3 Offset 0xc Length 1 (Bit position 0)
117
118 Gender = 1
119
120 Slot 2 Column 4 Offset 0xd Length 8
121
122 CreateTime = 05  4 2012 12:00AM
123
124 Slot 3 Offset 0xc0 Length 32
125
126 Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
127
128 Memory Dump @0x0823C0C0
129
130 00000000:   30001500 04000000 20000000 00000000 †0....... .......
131 00000010:   004ba000 000500e0 01002000 18521f66 †.K........ ..R.f
132
133 Slot 3 Column 0 Offset 0x4 Length 4
134
135 UserID = 4
136
137 Slot 3 Column 1 Offset 0x1c Length 4
138
139 UserName = 刘星
140
141 Slot 3 Column 2 Offset 0x8 Length 4
142
143 Age = 32
144
145 Slot 3 Column 3 Offset 0xc Length 1 (Bit position 0)
146
147 Gender = 0
148
149 Slot 3 Column 4 Offset 0xd Length 8
150
151 CreateTime = 05  8 2012 12:00AM
152
153 Slot 4 Offset 0xe0 Length 32
154
155 Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
156
157 Memory Dump @0x0823C0E0
158
159 00000000:   30001500 05000000 1b000000 01000000 †0...............
160 00000010:   0063a000 000500e0 01002000 0f5c5297 †.c........ ..\R.
161
162 Slot 4 Column 0 Offset 0x4 Length 4
163
164 UserID = 5
165
166 Slot 4 Column 1 Offset 0x1c Length 4
167
168 UserName = 小青
169
170 Slot 4 Column 2 Offset 0x8 Length 4
171
172 Age = 27
173
174 Slot 4 Column 3 Offset 0xc Length 1 (Bit position 0)
175
176 Gender = 1
177
178 Slot 4 Column 4 Offset 0xd Length 8
179
180 CreateTime = 06  1 2012 12:00AM
181
182 Slot 5 Offset 0x100 Length 32
183
184 Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
185
186 Memory Dump @0x0823C100
187
188 00000000:   30001500 06000000 10000000 01000000 †0...............
189 00000010:   0088a000 000500e0 01002000 8b736b51 †.......... ..skQ
190
191 Slot 5 Column 0 Offset 0x4 Length 4
192
193 UserID = 6
194
195 Slot 5 Column 1 Offset 0x1c Length 4
196
197 UserName = 王八
198
199 Slot 5 Column 2 Offset 0x8 Length 4
200
201 Age = 16
202
203 Slot 5 Column 3 Offset 0xc Length 1 (Bit position 0)
204
205 Gender = 1
206
207 Slot 5 Column 4 Offset 0xd Length 8
208
209 CreateTime = 07  8 2012 12:00AM
210
211 Slot 6 Offset 0x120 Length 32
212
213 Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
214
215 Memory Dump @0x0823C120
216
217 00000000:   30001500 07000000 2a000000 01000000 †0.......*.......
218 00000010:   00c0a000 000500e0 01002000 ed81415c †.......... ...A\
219
220 Slot 6 Column 0 Offset 0x4 Length 4
221
222 UserID = 7
223
224 Slot 6 Column 1 Offset 0x1c Length 4
225
226 UserName = 臭屁
227
228 Slot 6 Column 2 Offset 0x8 Length 4
229
230 Age = 42
231
232 Slot 6 Column 3 Offset 0xc Length 1 (Bit position 0)
233
234 Gender = 1
235
236 Slot 6 Column 4 Offset 0xd Length 8
237
238 CreateTime = 09  2 2012 12:00AM
239
240
241 DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。

View Code

我们再向索引视图插入更多数据使他出现聚集索引页

 1 --插入数据
 2 INSERT INTO index_View_Users ( [UserName], [Age], [Gender], [CreateTime] )
 3 SELECT '啊文',20,1,'2012-05-01' UNION ALL
 4 SELECT '宝文',23,0,'2012-05-05' UNION ALL
 5 SELECT '张武',38,1,'2012-05-04' UNION ALL
 6 SELECT '刘星',32,0,'2012-05-08' UNION ALL
 7 SELECT '小青',27,1,'2012-06-01' UNION ALL
 8 SELECT '王八',16,1,'2012-07-08' UNION ALL
 9 SELECT '臭屁',42,1,'2012-09-02'
10 GO 100

View Code

再看一下表中页面情况

1 --TRUNCATE TABLE [dbo].[DBCCResult]
2 INSERT INTO DBCCResult EXEC ('DBCC IND(pratice,index_View_Users,-1) ')
3
4 SELECT * FROM [dbo].[DBCCResult] ORDER BY [PageType] DESC 

View Code

我们看一下13571聚集索引页的内容

1 DBCC SHOWCONTIG(index_View_Users)
2 GO
3
4 DBCC SHOWCONTIG(stand_View_Users)
5 GO

1 SELECT * FROM sys.[dm_db_partition_stats] WHERE [object_id]=OBJECT_ID('index_View_Users')

小结

从上面的测试结果可以看出,索引视图已经跟基本表一样存储到硬盘中而且占用数据库空间

并且聚集索引页、数据页这些跟基本表的没有什么区别


插入数据到索引视图究竟做了什么操作?

我这里主要对基本表、标准视图、索引视图的数据插入和数据更新进行简单分析(主要看执行计划),看一下索引视图的更新究竟做了什么?

我在下面的测试里将执行计划导出来,大家可以把sqlplan文件拖到SSMS里就可以看到执行计划了

插入数据到基本表

 1 USE [pratice]
 2 GO
 3
 4 --插入数据到基本表
 5 INSERT INTO Users ( [UserName], [Age], [Gender], [CreateTime] )
 6 VALUES  ( N'nihao', -- UserName - nvarchar(50)
 7           30, -- Age - int
 8           1, -- Gender - bit
 9           '2013-08-29 03:40:36'  -- CreateTime - datetime
10           )

View Code

sqlplan下载:http://files.cnblogs.com/lyhabc/%E6%8F%92%E5%85%A5%E5%88%B0%E5%9F%BA%E6%9C%AC%E8%A1%A8.rar

插入数据到索引视图

 1 USE [pratice]
 2 GO
 3
 4 --插入数据到索引视图
 5 INSERT INTO index_View_Users ( [UserName], [Age], [Gender], [CreateTime] )
 6 VALUES  ( N'nihao', -- UserName - nvarchar(50)
 7           30, -- Age - int
 8           1, -- Gender - bit
 9           '2013-08-29 03:40:36'  -- CreateTime - datetime
10           )

View Code

sqlplan下载:http://files.cnblogs.com/lyhabc/%E6%8F%92%E5%85%A5%E5%88%B0%E7%B4%A2%E5%BC%95%E8%A7%86%E5%9B%BE.rar

插入数据到标准视图

 1 USE [pratice]
 2 GO
 3
 4 --插入数据到标准视图
 5 INSERT INTO stand_View_Users ( [UserName], [Age], [Gender], [CreateTime] )
 6 VALUES  ( N'nihao', -- UserName - nvarchar(50)
 7           30, -- Age - int
 8           1, -- Gender - bit
 9           '2013-08-29 03:40:36'  -- CreateTime - datetime
10           )

View Code

sqlplan下载:http://files.cnblogs.com/lyhabc/%E6%8F%92%E5%85%A5%E5%88%B0%E6%A0%87%E5%87%86%E8%A7%86%E5%9B%BE.rar

小结:

插入记录  

1、插入记录到基本表,会同时插入记录到索引视图  

2、插入记录到索引视图,会同时插入记录到基本表  

3、插入记录到标准视图,会同时插入记录到基本表和索引视图

因为标准视图没有物理存储到硬盘中,所以只插入数据到索引视图和基本表中


更新索引视图的数据究竟做了什么操作?

更新基本表数据

1 USE [pratice]
2 GO
3 --更新基本表数据
4 UPDATE  Users SET age=20 WHERE [UserID]=12

View Code

sqlplan下载:http://files.cnblogs.com/lyhabc/%E6%9B%B4%E6%96%B0%E5%9F%BA%E6%9C%AC%E8%A1%A8%E6%95%B0%E6%8D%AE.rar

更新索引视图数据

1 USE [pratice]
2 GO
3 --更新索引视图数据
4 UPDATE  index_View_Users SET age=20 WHERE [UserID]=12

View Code

sqlplan下载:http://files.cnblogs.com/lyhabc/%E6%9B%B4%E6%96%B0%E7%B4%A2%E5%BC%95%E8%A7%86%E5%9B%BE%E6%95%B0%E6%8D%AE.rar

更新标准视图数据

1 USE [pratice]
2 GO
3 --更新标准视图数据
4 UPDATE  stand_View_Users SET age=20 WHERE [UserID]=12

View Code

sqlplan下载:http://files.cnblogs.com/lyhabc/%E6%9B%B4%E6%96%B0%E6%A0%87%E5%87%86%E8%A7%86%E5%9B%BE%E6%95%B0%E6%8D%AE.rar

小结:

更新记录  

1、更新基本表记录,会同时更新索引视图记录  

2、更新索引视图记录,会同时更新基本表记录  

3、更新标准视图记录,会同时更新基本表和索引视图记录


总结

从上面的实验可以看出无论是插入记录还是更新记录,基本表和索引视图都需要进行同步插入和更新记录,如果索引视图引用多个基本表

那么这个开销也是不小的

 

我们公司的系统中的数据库表是没有一个外键跟视图的!!

我的猜想:
1、增加冗余字段,尽量不使用外键,其实增加冗余字段也可以解决视图问题,因为视图可以引用多张表
2、视图在插入记录和更新记录的时候会增加额外开销
3、如果需要级联更新,就使用事务更新两个表,插入记录也是一样
4、报表也会引用多张表,那么使用多表连接的SQL语句来解决一张报表引用多张基本表的问题,不用视图

 


补充

删除了聚集索引之后,索引视图是否会变成标准视图呢?

1 DROP INDEX CIX_View_Users ON index_View_Users

插入数据到基本表

1 --插入数据到基本表
2 INSERT INTO Users ( [UserName], [Age], [Gender], [CreateTime] )
3 VALUES  ( N'nihao', -- UserName - nvarchar(50)
4           30, -- Age - int
5           1, -- Gender - bit
6           '2013-08-29 03:40:36'  -- CreateTime - datetime
7           )

View Code

可以看到索引视图已经没有了

查询视图数据的时候还可以查询,证明索引视图已经退化为标准视图了

如有不对的地方,欢迎大家拍砖o(∩_∩)o

转载于:https://www.cnblogs.com/lyhabc/p/3312150.html

索引视图是否物理存储在数据库中以及使用索引视图的一些见解相关推荐

  1. 将不同数据存储到数据库中_如何将数据存储在兔子洞中

    将不同数据存储到数据库中 Starting with databases and venturing into how the physical components of a computer st ...

  2. MySQL:如何将树形结构存储在数据库中

    文章目录 问题 方案一 Adjacency List(存储父节点) 数据库存储结构 SQL示例 1.添加节点 2.查询小天的直接上司 3.查询老宋管理下的直属员工 4.查询小天的所有上司 5.查询老王 ...

  3. java rsa 存数据库_java – 如何创建RSA密钥对以便将其存储在数据库中?

    我正在尝试实现变异加密算法(理论上由我开发)并作为需求的一部分,我需要生成一个RSA密钥对并将其存储在数据库中,以便以后作为加密过程的一部分进行检索(仅用于加密会话密钥,以便可以使用加密的消息安全地发 ...

  4. php将soap返回的xml转成数组,PHP – 在PHP中将XML转换为数组 – 在php中解析soap xml并将其存储在数据库中...

    我想转换soap xml响应并将其存储在数据库中.这是我的XML. 200 example2 ex2 example2@example2.com example2, example2 example2 ...

  5. android 对象数据库中,解析嵌套的JSON对象,并存储在数据库中的Android

    我只是试图让存储在我的JSON文件中的值,并将其保存到SQLite数据库:解析嵌套的JSON对象,并存储在数据库中的Android 这是我的JSON文件: { "list": { ...

  6. 如何用DELPHI实现把WORD、EXCEL和图片等存储到数据库中

    如何用DELPHI实现把WORD.EXCEL和图片等存储到数据库中 用image字段保存这些文档.     var         word_stream:   TMemoryStream;      ...

  7. python爬取携程网航班机票信息并存储到数据库中,2020年最新版本

    我们先看一下携程网的信息 从以上我们可以获取两个信息 1.我是从上海到成都的 2.7条航班信息 教你如何爬虫 我不教静态网页的爬虫,因为太简单了:我们直接上手携程网 我们到这个上述这个页面以后,我推荐 ...

  8. Kettle 使用资源库功能把ktr元数据统一存储到数据库中

    原创作品,出自 "深蓝的blog" 博客,欢迎转载,转载时请务必注明出处,否则追究版权法律责任. 深蓝的blog:http://blog.csdn.net/huangyanlong ...

  9. 如何在Python中将数字文件存储在数据库中

    Databases like MySQL and PostgreSQL are all ideal for storing tables with numeric and text data. How ...

最新文章

  1. CSDN湘苗培优|火热报名中
  2. spring配置datasource三种方式
  3. tab css html,纯css的tab 切换
  4. async 打包异常_重新打包流中的异常
  5. 发那科攻丝回退参数_参数-Fanuc数控系统的攻丝拉拔动作倍率即回退速度倍率
  6. 游戏业界“大地震”!687亿美元,微软天价收购动视暴雪
  7. jQtouch 初体验
  8. 产品经理学习总结(1)——人人都是产品经理之需求文档语法
  9. WinAPI: 钩子回调函数之 CallWndProcRetProc
  10. linux的manual手册不存在,Linux笔记
  11. Debian忘记密码修改
  12. # 学号20155308 2006-2007-2 《Java程序设计》第4周学习总结
  13. SpringMVC Redirect 跳转后保存Model中的数据
  14. UPS 笔记 (逆变电源 DSP)
  15. [Android] Codec paramter
  16. Chinese Std GBT7714-2015.ens EndNote 样式文件
  17. 8w 字,给程序员的职场第一课(上篇)
  18. 户外直播 4G/5G户外高清直播 5G视频回传
  19. Squid缓存服务器和代理介绍
  20. css3,background-clip/background-origin的使用场景,通俗讲解

热门文章

  1. 【总结】线性代数的本质 - 2
  2. Dynamically Loaded (DL)
  3. 【学习笔记】DeepCrossing
  4. 《STL源码剖析》读书笔——(1)空间配置器
  5. 著名数据恢复工具有哪些是好用的
  6. 利用Vue.js实现简单员工管理系统(增删查)的功能
  7. Python开发 之 去除字符串中 首个指定字符串
  8. Python全栈(十)Django框架之9.聚合函数和表达式
  9. 女性常掉头发的应对法(zt)
  10. 第三方支付接口开发及开发中遇到的坑爹问题