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


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

前言

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

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM