雖然對於keyhashvalue的研究還有很多問題還沒有解決,但是基本可以確定“keyhashvalue是用來鎖 定資源的”
而不是我之前說的,在seek的時候根據這個KeyHashValue來快速查找到對應的記錄
誤導大家了,真的不好意思!!!!
資源 說明
RID 用於鎖定堆(heap)中的某一行
KEY 用於鎖定索引上的某一行,或者某個索引鍵
PAGE 鎖定數據庫中的一個8KB頁,例如數據頁或索引頁
EXTENT 一組連續的8頁(區)
HOBT 鎖定整個堆或B樹的鎖
TABLE 鎖定包括所有數據和索引的整個表
FILE 數據庫文件
APPLICATION 應用程序專用的資源
METADATA 元數據鎖
ALLOCATION_UNIT 分配單元
DATABASE 整個數據庫
KEY是靠生成的這個KeyHashValue來進行鎖定索引中的行
KEY 用於鎖定索引上的某一行
為什麼需要這個KeyHashValue???
由於很苟很苟沒有寫C#代碼,不過我覺得從C#的多線程同步來理解會更加好
例如:
lock 語句 lock 確保當一個線程位於代碼的臨界區時,另一個線程不進入臨界區。如果其他線程試圖 進入鎖定的代
碼,則它將一直等待(即被阻止),直到該對象被釋放,大家可以把同步對象理解為 KeyHashValue
c# 多線程同步
c# 多線程同步
大家還是看給出的文章鏈接吧,因為本人很苟很苟沒有寫C#代碼了,細節的東西看文章比較好
網上有很多相關的文章:
例如
建立索引的時候為什麽有900bytes的限制
為了性能,不可能讓您在比較大的數據類型下,而且存儲了非常多的數據的字段上建立索引
因為這樣做的話,要計算出KeyHashValue就會非常消耗性能
這篇文章:Improvement in minimizing lockhash key collisions in SQL Server 2008R2 and its impact on concurrency
Since the key to a row could be as large as 900 bytes, using the real key values would have inflicted larger memory consumption.
引入
The solution to this problem was found when designing SQL server 7.0 in 1996 and 1997 by using the key of the row and apply
a hash algorithm to it which then results in a 6 byte long lockhash value
我將這些文章整理到我的文章裡:undocumented virtual column %%lockres%%
在SQLSERVER2005下跟SQLSERVER2012下,建立相同的聚集索引,你會看到在SQL2005下,表的聚集索引頁面有 KeyHashValue
但是在SQL2012下,表的聚集索引頁面的KeyHashValue列全部為NULL
由於我沒有SQL2008,所以沒有測試SQL2008,估計從SQL2008開始,KeyHashValue開始有些變化了
在SQL2005裡,你使用dbcc page查看數據頁面,數據頁面裡的每行記錄是沒有顯示KeyHashValue 的,不知道要打開哪個跟蹤標記才能看到
在SQL2005裡唯一能看到數據頁面中的keyhashvalue只有使用%%lockres%%
而在SQL2012,不用做任何設置,使用dbcc page就可以看到KeyHashValue
當然也可以用%%lockres%%:
1 SELECT %%lockres%% AS '數據頁的keyhashvalue' FROM 表名
頁面126是數據頁面
1 DBCC TRACEON(3604,-1) 2 GO 3 DBCC PAGE(testhashkey,1,126,3) 4 GO
Slot 0 Offset 0x0 Length 0 Length (physical) 0
KeyHashValue = (8194443284a0)
DBCC 執行完畢。如果 DBCC 輸出了錯誤信息,請與系統管理員聯系。
SQL2012最大的改進是提示非常清晰,而且以前的SQLSERVER版本沒有顯示出來的東西都給你顯示出來了,
這樣有時候就不用做那麼多系統表的表連接,如果是以前版本的SQLSERVER要查看某一個信息的時候又要做
這個系統表的表連接又要做那個表的表連接才能得出這個自己想看的東西,非常繁瑣