Vấn đề đầu tiên trong kịch bản thử nghiệm của bạn là bảng không có chỉ mục hữu ích trên firstname
. Thứ hai là bảng trống.
Từ Khóa dãy khóa trong BOL
Không có chỉ mục phù hợp để lấy RangeS-S
khóa như vậy để đảm bảo ngữ nghĩa có thể tuần tự hóa SQL Server cần khóa toàn bộ bảng.
Nếu bạn thử thêm chỉ mục theo nhóm trên bảng trên cột tên như bên dưới và lặp lại thử nghiệm ...
CREATE CLUSTERED INDEX [IX_FirstName] ON [dbo].[dummy] ([firstname] ASC)
... bạn sẽ thấy rằng bạn vẫn bị chặn!
Mặc dù thực tế là một chỉ mục phù hợp hiện đã tồn tại và kế hoạch thực thi cho thấy rằng nó được tìm kiếm để đáp ứng truy vấn.
Bạn có thể biết lý do tại sao bằng cách chạy phần sau
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT *
FROM dummy
WHERE firstname = 'abc'
SELECT resource_type,
resource_description,
request_mode
FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID
COMMIT
Trả lại
+---------------+----------------------+--------------+
| resource_type | resource_description | request_mode |
+---------------+----------------------+--------------+
| DATABASE | | S |
| OBJECT | | IS |
| PAGE | 1:198 | IS |
| KEY | (ffffffffffff) | RangeS-S |
+---------------+----------------------+--------------+
SQL Server không chỉ lấy ra một khóa phạm vi trên chính xác phạm vi mà bạn chỉ định trong truy vấn của mình.
Đối với một vị từ bình đẳng trên một chỉ mục duy nhất nếu có một khóa phù hợp, nó sẽ chỉ thực hiện một khóa thông thường chứ không phải bất kỳ loại khóa phạm vi nào.
Đối với một vị từ tìm kiếm không phải là duy nhất, nó sẽ loại bỏ các khóa trên tất cả các khóa phù hợp trong phạm vi cộng với khóa "tiếp theo" ở cuối phạm vi (hoặc trên ffffffffffff
đại diện cho vô hạn nếu không tồn tại khóa "tiếp theo"). Ngay cả các bản ghi "ma" đã bị xóa
có thể được sử dụng trong phạm vi khóa phím này.
Như được mô tả ở đây cho một vị từ bình đẳng trên một chỉ mục duy nhất hoặc không duy nhất
Vì vậy, với một bảng trống, SELECT
cuối cùng vẫn bị khóa toàn bộ chỉ mục. Trước đó bạn cũng cần phải chèn một hàng giữa abc
và lmn
và sau đó chèn của bạn sẽ thành công.
insert into dummy values('def', 'def')