想说一下动手做实验的重要性

想说一下动手做实验的重要性

前言

有时候一个人会有很多想法,或者当你看到别人的文章的时候你会有想法,又或者想验证一下别人的观点

这时候就需要自己动手做实验来验证了,想法无处不在

比如:我delete了一条数据,我能不能通过事务日志[fn_dblog]()把他恢复呢?如果能恢复我能不能写一个

数据库恢复工具来恢复已经delete了的数据???

 

您需要不断地去想,用自己所学到的知识去设计实验并证明自己的想法

再比如:我现在看到一篇文章《SQL Server中使用带有Persisted值的计算列

文章地址:http://database.ctocio.com.cn/dbzjdysummary/48/8730048.shtml

想法:究竟带有Persisted值的计算列数据会不会存储到磁盘上???

带着这个疑问,我们做一下下面实验


动手实验环节

使用下面SQL代码建立测试环境

 1 --创建测试表
 2 USE [tempdb]
 3 GO
 4 CREATE TABLE [dbo].[CCtest]
 5 (
 6   [empNumb] [int] NULL ,
 7   [DOBirth] [datetime] NULL ,
 8   [DORetirement] AS ( DATEADD(year, ( 60 ), [DOBirth]) - ( 1 ) ) PERSISTED
 9 )
10 GO
11 
12 --插入测试数据
13 USE [tempdb]
14 GO
15 INSERT  INTO CCTest ( empNumb, DOBirth )
16         SELECT  30, '1985-12-13'
17         UNION ALL
18         SELECT  25, '1980-11-18'
19         UNION ALL
20         SELECT  21, '1978-01-19'
21         UNION ALL
22         SELECT  7, '1985-12-13'
23         UNION ALL
24         SELECT  5, '1975-07-23'
25 GO
26 
27 SELECT  * FROM    dbo.CCTest
28 GO
View Code


再使用下面代码看一下表中的数据页是哪一个

 1 --创建一个表,用来保存DBCC IND的结果
 2 USE  [tempdb]
 3 GO
 4 CREATE TABLE DBCCResult
 5 (
 6   PageFID NVARCHAR(200) ,
 7   PagePID NVARCHAR(200) ,
 8   IAMFID NVARCHAR(200) ,
 9   IAMPID NVARCHAR(200) ,
10   ObjectID NVARCHAR(200) ,
11   IndexID NVARCHAR(200) ,
12   PartitionNumber NVARCHAR(200) ,
13   PartitionID NVARCHAR(200) ,
14   iam_chain_type NVARCHAR(200) ,
15   PageType NVARCHAR(200) ,
16   IndexLevel NVARCHAR(200) ,
17   NextPageFID NVARCHAR(200) ,
18   NextPagePID NVARCHAR(200) ,
19   PrevPageFID NVARCHAR(200) ,
20   PrevPagePID NVARCHAR(200)
21 )
22 GO
23 
24 --PageType          页面类型:1:数据页面;2:索引页面;3:Lob_mixed_page;4:Lob_tree_page;10:IAM页面
25 --
26 --IndexID            索引ID:0 代表堆, 1 代表聚集索引, 2-250 代表非聚集索引 大于250就是text或image字段
27 
28 
29 INSERT INTO DBCCResult EXEC ('DBCC IND(tempdb,CCtest,-1) ')
30 
31 SELECT * FROM [dbo].[DBCCResult] ORDER BY [PageType] DESC 
View Code

可以看到数据页是78

用下面SQL语句看一下数据页78的内容

1 DBCC TRACEON(3604,-1)
2 GO
3 DBCC PAGE([tempdb],1,78,3) 
4 GO
  1 DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。
  2 
  3 PAGE: (1:78)
  4 
  5 
  6 BUFFER:
  7 
  8 
  9 BUF @0x03E63850
 10 
 11 bpage = 0x16248000                   bhash = 0x00000000                   bpageno = (1:78)
 12 bdbid = 2                            breferences = 0                      bUse1 = 5146
 13 bstat = 0x1c0000b                    blog = 0x2159bbbb                    bnext = 0x00000000
 14 
 15 PAGE HEADER:
 16 
 17 
 18 Page @0x16248000
 19 
 20 m_pageId = (1:78)                    m_headerVersion = 1                  m_type = 1
 21 m_typeFlagBits = 0x4                 m_level = 0                          m_flagBits = 0x8008
 22 m_objId (AllocUnitId.idObj) = 88     m_indexId (AllocUnitId.idInd) = 256  
 23 Metadata: AllocUnitId = 72057594043695104                                 
 24 Metadata: PartitionId = 72057594038714368                                 Metadata: IndexId = 0
 25 Metadata: ObjectId = 37575172        m_prevPage = (0:0)                   m_nextPage = (0:0)
 26 pminlen = 24                         m_slotCnt = 6                        m_freeCnt = 7949
 27 m_freeData = 285                     m_reservedCnt = 27                   m_lsn = (37:284:165)
 28 m_xactReserved = 27                  m_xdesId = (0:1007)                  m_ghostRecCnt = 0
 29 m_tornBits = 0                       
 30 
 31 Allocation Status
 32 
 33 GAM (1:2) = ALLOCATED                SGAM (1:3) = ALLOCATED               
 34 PFS (1:1) = 0x61 MIXED_EXT ALLOCATED  50_PCT_FULL                         DIFF (1:6) = CHANGED
 35 ML (1:7) = NOT MIN_LOGGED            
 36 
 37 Slot 0 Offset 0x60 Length 27
 38 
 39 Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP     
 40 Memory Dump @0x080FC060
 41 
 42 00000000:   10001800 1e000000 00000000 a07a0000 †.............z..         
 43 00000010:   00000000 3ad00000 0300f8†††††††††††††....:......              
 44 
 45 Slot 0 Column 0 Offset 0x4 Length 4
 46 
 47 empNumb = 30                         
 48 
 49 Slot 0 Column 1 Offset 0x8 Length 8
 50 
 51 DOBirth = 12 13 1985 12:00AM         
 52 
 53 Slot 0 Column 2 Offset 0x10 Length 8
 54 
 55 DORetirement = 12 12 2045 12:00AM    
 56 
 57 Slot 1 Offset 0x7b Length 27
 58 
 59 Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP     
 60 Memory Dump @0x080FC07B
 61 
 62 00000000:   10001800 19000000 00000000 ee550000 †.............U..         
 63 00000010:   00000000 88ab0000 0300f8†††††††††††††...........              
 64 
 65 Slot 1 Column 0 Offset 0x4 Length 4
 66 
 67 empNumb = 25                         
 68 
 69 Slot 1 Column 1 Offset 0x8 Length 8
 70 
 71 DOBirth = 03 25 1960 12:00AM         
 72 
 73 Slot 1 Column 2 Offset 0x10 Length 8
 74 
 75 DORetirement = 03 24 2020 12:00AM    
 76 
 77 Slot 2 Offset 0x96 Length 27
 78 
 79 Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP     
 80 Memory Dump @0x080FC096
 81 
 82 00000000:   10001800 15000000 00000000 5b6f0000 †............[o..         
 83 00000010:   00000000 f5c40000 0300f8†††††††††††††...........              
 84 
 85 Slot 2 Column 0 Offset 0x4 Length 4
 86 
 87 empNumb = 21                         
 88 
 89 Slot 2 Column 1 Offset 0x8 Length 8
 90 
 91 DOBirth = 01 19 1978 12:00AM         
 92 
 93 Slot 2 Column 2 Offset 0x10 Length 8
 94 
 95 DORetirement = 01 18 2038 12:00AM    
 96 
 97 Slot 3 Offset 0xb1 Length 27
 98 
 99 Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP     
100 Memory Dump @0x080FC0B1
101 
102 00000000:   10001800 07000000 00000000 a07a0000 †.............z..         
103 00000010:   00000000 3ad00000 0300f8†††††††††††††....:......              
104 
105 Slot 3 Column 0 Offset 0x4 Length 4
106 
107 empNumb = 7                          
108 
109 Slot 3 Column 1 Offset 0x8 Length 8
110 
111 DOBirth = 12 13 1985 12:00AM         
112 
113 Slot 3 Column 2 Offset 0x10 Length 8
114 
115 DORetirement = 12 12 2045 12:00AM    
116 
117 Slot 4 Offset 0xcc Length 27
118 
119 Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP     
120 Memory Dump @0x080FC0CC
121 
122 00000000:   10001800 05000000 00000000 cc6b0000 †.............k..         
123 00000010:   00000000 66c10000 0300f8†††††††††††††....f......              
124 
125 Slot 4 Column 0 Offset 0x4 Length 4
126 
127 empNumb = 5                          
128 
129 Slot 4 Column 1 Offset 0x8 Length 8
130 
131 DOBirth = 07 23 1975 12:00AM         
132 
133 Slot 4 Column 2 Offset 0x10 Length 8
134 
135 DORetirement = 07 22 2035 12:00AM    
136 
137 
138 DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。
View Code
 1 Slot 4 Offset 0xcc Length 27
 2 
 3 Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP     
 4 Memory Dump @0x080FC0CC
 5 
 6 00000000:   10001800 05000000 00000000 cc6b0000 †.............k..         
 7 00000010:   00000000 66c10000 0300f8†††††††††††††....f......              
 8 
 9 Slot 4 Column 0 Offset 0x4 Length 4
10 
11 empNumb = 5                          
12 
13 Slot 4 Column 1 Offset 0x8 Length 8
14 
15 DOBirth = 07 23 1975 12:00AM         
16 
17 Slot 4 Column 2 Offset 0x10 Length 8
18 
19 DORetirement = 07 22 2035 12:00AM    

可以看到[DORetirement]列真的存储到磁盘上

那么计算列是怎麽通过计算插入到表中,或者更新表的[DOBirth]列是怎麽顺带更新[DORetirement]列的??

我们可以看一下执行计划,从执行计划中看能否看出端砚

这里应该使用SET STATISTICS PROFILE ON 才行,用图形化的执行计划看不到每个运算符里面具体做了什么

1 SET STATISTICS PROFILE ON 
2 GO
3 INSERT INTO [dbo].[CCtest] ( [empNumb], [DOBirth] )
4 VALUES  ( 89, -- empNumb - int
5           '2013-08-22 11:48:46'  -- DOBirth - datetime
6           )

在插入之前已经做了dateadd函数的计算,也就是在“计算标量”这个运算符里做的

更新语句也是一样

1 SET STATISTICS PROFILE ON 
2 GO
3 UPDATE CCtest SET DOBirth = '1960-03-25' WHERE empnumb = 25
4 GO

 

可以看到update语句和insert语句都有“计算标量”运算符,dateadd函数的运算就在“计算标量”运算符里做的


个人意见

其实,做完实验还可以写一篇博文把实验过程记录下来,例如在博客园里写文章,以后很大机会会用到的

我个人建议写成博文比较好,或许您的想法还可以继续深入研究,当您以后遇到跟您的想法差不多的问题解决方案的时候,这时候您就能够体会到

把想法写成博文的好处,您能够针对之前写的博文继续深入研究或者修正之前博文的错误

 

在工作中当大伙讨论某个解决方案的时候,你就更有底气了,你可以根据自己做过的实验给出自己的解决方案,而不是人云亦云

可能您自己的解决方案不是最合适的,但是最起码您为解决方案出了自己的一份力,甚至您可以把自己的博文拿出来给大家看证明自己的观点

当然实验环境跟真实环境会有很大差别,但是最起码您大概会估计得到有什么后果,并且知道个中的原理

例如:某个表查询很慢,你会想到加索引,那么加聚集索引好呢?还是加非聚集索引好呢?

加了之后副作用会不会很大呢?你做过实验之后,知道聚集索引和非聚集索引的区别,

结合当前情况,我相信您可以作出正确选择

 

如果有一些问题没有实验环境,或者做实验也解决不了,或者自己达不到那个水平不知道怎样做,这时候没办法了,只能请教高人了

或者寄希望于日后,能否出现您遇到的问题并且有相应的实验环境

 

既然这些简单的实验只需要两三分钟的事情,为什麽自己不亲自动手做一下实验呢?o(∩_∩)o

 

--------------------------------------------------------------------

题外话
可能您写出来的文章,做出来的实验没有人评论,没有人能纠正自己的错误,我做的实验结果不知道对不对,这时候不要泄气
除了别人主动看你的文章,你也要主动看别人的文章,我的习惯就是看到好文章马上copyevernote
当然将别人的知识化为自己的并理解透彻需要很长时间的
 
本人关注了园子里300多人,收藏了非常多的文章 ,我相信一定有人在日后能够看到自己写的文章,做的实验并作出评论的
相信自己!!!
 
 
如有不对的地方,欢迎大家强烈拍砖o(∩_∩)o
posted @ 2013-08-27 20:34  桦仔  阅读(3770)  评论(15编辑  收藏  举报