天天看點

想說一下動手做實驗的重要性

想說一下動手做實驗的重要性

前言

有時候一個人會有很多想法,或者當你看到别人的文章的時候你會有想法,又或者想驗證一下别人的觀點

這時候就需要自己動手做實驗來驗證了,想法無處不在

比如:我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       

可以看到資料頁是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

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

題外話

可能您寫出來的文章,做出來的實驗沒有人評論,沒有人能糾正自己的錯誤,我做的實驗結果不知道對不對,這時候不要洩氣

除了别人主動看你的文章,你也要主動看别人的文章,我的習慣就是看到好文章馬上copy到evernote裡

當然将别人的知識化為自己的并了解透徹需要很長時間的

本人關注了園子裡300多人,收藏了非常多的文章 ,我相信一定有人在日後能夠看到自己寫的文章,做的實驗并作出評論的

相信自己!!!

想說一下動手做實驗的重要性
想說一下動手做實驗的重要性

如有不對的地方,歡迎大家強烈拍磚o(∩_∩)o

繼續閱讀