假設我們有一個表Users
只有3列。SQL Server:鎖和獨佔類型的選擇
UserId - primary key clustered int
Username - nvarchar(50)
CityId - int, which has a non-unique non-clustered index (mouthful).
如果我做了選擇,並帶有專用鎖和一個標籤的begin tran:
declare @CityId int = 10
begin tran
SELECT *
FROM [dbo].Users WITH (XLOCK,INDEX (MyCityIndex))
WHERE CityId = @CityId
而且注意到我不提交或回滾事務。
然後在另一個(YES另一個選項卡ELSE SQL會做一些優化和慣於工作)選項卡上,我跑:
declare @CityId int = 10
begin tran
SELECT *
FROM [dbo].Users WITH (XLOCK, INDEX (MyCityIndex))
WHERE CityId = @CityId
,如果我用同樣的CityId
(10)很明顯我們阻塞。但我猜如果我使用CityId = 11
會發生什麼?
declare @CityId int = 11
它會工作。
但它會工作,如果我做索引提示搜索,否則它將無法正常工作,即使我把CityId = 11
,然後它會阻止和等待其他tran會失敗。
這是怎麼回事?
當它使用獨佔鎖讀取數據時,執行全表掃描,然後一旦它遇到記錄被鎖定,就會被阻止?真?
如果索引得到碎片並且碰到實際上被阻塞的不包含其'id'的行,會發生什麼情況。那塊還會嗎?
在進行測試時,請使用2個不同的選項卡進行選擇,因爲這裏有SQL Server優化。
我使用SQL Server 2014
ty爲答案,但你仍然沒有回答我的問題。在做'select ... where ..'語句時,實際上是否打鎖記錄?如果索引是分散的並且包含不應存在的數據會怎麼樣?我的解決方案是否仍然有效? – Aflred
@Afred,我在我的答案中添加了一個腳本,表明即使沒有索引提示,查詢也不會被搜索阻塞。碎片不會導致索引頁面包含它不應該包含的數據;它可能會降低頁面預期壽命並導致更多的IO。 –
這就是我正在得到的確切行爲,並且它是正確的,並且可以自己實際嘗試它。是的,您已使用'分段不會導致索引頁包含它不應該包含的數據來回答我的整個問題。它可能會降低頁面預期壽命,並導致更多的IO',所以這就是我的指數錯了'。我猜這一切都取決於SQL優化計劃。 – Aflred