Máy chủ SQL NOLOCK và tham gia


153

Bối cảnh: Tôi có một truy vấn quan trọng về hiệu năng mà tôi muốn chạy và tôi không quan tâm đến việc đọc bẩn.

Câu hỏi của tôi là; Nếu tôi đang sử dụng các phép nối, tôi có phải chỉ định gợi ý NOLOCK cho những thứ đó không?

Ví dụ; Là:

SELECT * FROM table1 a WITH (NOLOCK)
INNER JOIN table2 b WITH (NOLOCK) ON a.ID = b.ID

Tương đương với:

SELECT * FROM table1 a WITH (NOLOCK)
INNER JOIN table2 b ON a.ID = b.ID

Hoặc tôi sẽ cần chỉ định (NOLOCK)gợi ý về việc tham gia để đảm bảo tôi không khóa bảng đã tham gia?

Câu trả lời:


166

Tôi sẽ không giải quyết READ UNCOMMITTEDtranh luận, chỉ là câu hỏi ban đầu của bạn.

Có, bạn cần WITH(NOLOCK)trên mỗi bảng tham gia. Không, truy vấn của bạn không giống nhau.

Hãy thử bài tập này. Bắt đầu một giao dịch và chèn một hàng vào bảng1 và bảng2. Đừng cam kết hoặc phục hồi giao dịch nào. Tại thời điểm này, truy vấn đầu tiên của bạn sẽ trả về thành công và bao gồm các hàng không được cam kết; truy vấn thứ hai của bạn sẽ không trả về vì bảng2 không có WITH(NOLOCK)gợi ý về nó.


18

Tôi khá chắc chắn rằng bạn cần chỉ định NOLOCKcho mỗi JOINtrong truy vấn. Nhưng kinh nghiệm của tôi chỉ giới hạn ở SQL Server 2005.

Khi tôi tra cứu MSDN chỉ để xác nhận, tôi không thể tìm thấy bất cứ điều gì rõ ràng. Các tuyên bố dưới đây dường như làm tôi nghĩ rằng, trong năm 2008, hai tuyên bố của bạn ở trên là tương đương nhau mặc dù trong năm 2005 thì không phải vậy:

[Máy chủ SQL 2008 R2]

Tất cả các gợi ý khóa được truyền đến tất cả các bảng và dạng xem được truy cập bởi gói truy vấn , bao gồm các bảng và dạng xem được tham chiếu trong dạng xem. Ngoài ra, SQL Server thực hiện kiểm tra tính nhất quán khóa tương ứng.

[Máy chủ SQL 2005]

Trong SQL Server 2005, tất cả các gợi ý khóa được truyền đến tất cả các bảng và dạng xem được tham chiếu trong dạng xem. Ngoài ra, SQL Server thực hiện kiểm tra tính nhất quán khóa tương ứng.

Ngoài ra, điểm cần lưu ý - và điều này áp dụng cho cả năm 2005 và 2008:

Gợi ý bảng được bỏ qua nếu bảng không được truy cập bởi kế hoạch truy vấn. Điều này có thể được gây ra bởi trình tối ưu hóa chọn hoàn toàn không truy cập vào bảng hoặc do một chế độ xem được lập chỉ mục được truy cập thay thế. Trong trường hợp sau, việc truy cập chế độ xem được lập chỉ mục có thể được ngăn chặn bằng cách sử dụng OPTION (EXPAND VIEWS)gợi ý truy vấn.


@In Sane: Thú vị ... cảm ơn vì điều đó ... Tôi cho rằng tôi không làm hại gì bằng cách đưa nó vào THAM GIA, ngay cả khi điều đó không hoàn toàn cần thiết? Tài liệu về NOLOCK khá thưa thớt như bạn đã đề cập; Tôi gặp khó khăn trong việc tìm kiếm bất cứ điều gì kết luận bản thân mình.
DanP

2
@InSane: Bạn lấy thông tin này từ đâu? Nó dường như đi ngược lại câu trả lời được chấp nhận.
Jay Sullivan

1
@notfed - tham khảo TechNet liên kết technet.microsoft.com/en-us/library/ms187373(v=sql.105).aspx - bạn có thể thay đổi phiên bản cơ sở dữ liệu ở trên để so sánh các bài viết tương tự cho các phiên bản khác nhau của db
Jagmag

2
Văn bản năm 2005 nói về XEM. Vì vậy, nếu bạn thực hiện "từ myview with (nolock)" thì nó nói rằng nolock được truyền tới tất cả các bảng và các khung nhìn liên quan đến myview (bạn có thể có 10 tham gia trong đó). Không chắc chắn chính xác văn bản năm 2008 có nghĩa là gì khi nó thêm "truy cập bởi kế hoạch truy vấn" bên cạnh các khung nhìn.
Thierry_S

9

Cũng không. Bạn đặt mức cô lập READ UNCOMMITTEDluôn tốt hơn so với đưa ra gợi ý khóa riêng lẻ. Hoặc, tốt hơn nữa, nếu bạn quan tâm đến các chi tiết như tính nhất quán , hãy sử dụng cách ly ảnh chụp nhanh .


@Remus: Tôi không chắc chắn rằng tôi có thể sử dụng READ UNCOMMITTED trong trường hợp của mình vì tôi đang truy cập kết nối qua NHibernate để thực hiện cuộc gọi ADO.NET thô đặc biệt; điều này có thể được chỉ định nội tuyến trong truy vấn không, hoặc nó sẽ tuân theo cấp độ giao dịch có trên giao dịch NHibernate?
DanP

Kết thúc cuộc gọi using (TransactionScope scope=new TransactionScope(..., TransactionOptions) {...}và thiết lập các IsolationLeveltùy chọn: msdn.microsoft.com/en-us/l Library / Giả
Remus Rusanu

@Remus: Thật không may, quản lý giao dịch được quan tâm ở mức cao hơn nhiều so với điều này, vì vậy đó cũng không phải là một lựa chọn.
DanP

Tôi hiểu rồi. Sau đó, để trả lời câu hỏi của bạn: NOLOCK là một gợi ý bảng và do đó, nó áp dụng cho các hàng được thêm vào (bảng, chế độ xem, TVF, v.v.). Nếu bạn có nhiều hàng được nối trong một truy vấn, mỗi truy vấn sẽ cần gợi ý NOLOCK riêng.
Remus Rusanu

2
Nhưng bạn đã xem xét cách ly ảnh chụp chưa? ALTER DATABASE ... SET READ_COMMITTED_SNAPSHOT ON;. Kết quả thật ngoạn mục, vì tất cả các lần đọc cam kết bình thường đều chuyển thành đọc ảnh chụp nhanh, khóa miễn phí nhưng vẫn nhất quán. Chi phí được tăng tempdbtải: msdn.microsoft.com/en-us/l Library / ms175492.aspx
Remus Rusanu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.