2008-10-16 45 views
167

Tôi đoán câu hỏi thực sự là:Ảnh hưởng của NOLOCK gợi ý trong câu SELECT

Nếu tôi không quan tâm đến bẩn lần đọc, sẽ thêm với (NOLOCK) gợi ý để một câu lệnh SELECT ảnh hưởng đến hiệu suất của:

  1. SELECT tuyên bố hiện tại
  2. các giao dịch khác so với bảng cho

Ví dụ:

Select * 
from aTable with (NOLOCK) 
+2

Các câu trả lời [SO] (http://stackoverflow.com/a/12610346/641833) và [DBA] (http://dba.stackexchange.com/a/50029/9210) này rõ ràng hơn một chút về những gì đang thực sự xảy ra. – Trisped

Trả lời

242

1) , một lựa chọn với NOLOCK sẽ hoàn thành nhanh hơn so với một lựa chọn bình thường.

2) , lựa chọn với NOLOCK sẽ cho phép các truy vấn khác đối với bảng được thực hiện hoàn thành nhanh hơn lựa chọn bình thường.

Tại sao điều này?

NOLOCK thông thường (tùy thuộc vào công cụ DB) có nghĩa là cung cấp dữ liệu cho tôi và tôi không quan tâm trạng thái của nó và không bận tâm giữ nó trong khi bạn đọc từ đó. Đó là tất cả cùng một lúc nhanh hơn, ít tốn nhiều tài nguyên và rất nguy hiểm.

Bạn nên được cảnh báo để không bao giờ thực hiện cập nhật từ hoặc thực hiện bất kỳ hệ thống nào quan trọng hoặc yêu cầu tính chính xác tuyệt đối bằng cách sử dụng dữ liệu bắt nguồn từ số đọc NOLOCK. Hoàn toàn có thể là dữ liệu này chứa các hàng đã bị xóa trong khi chạy truy vấn hoặc đã bị xóa trong các phiên khác chưa được hoàn thành. Có thể dữ liệu này bao gồm các hàng đã được cập nhật một phần. Có thể dữ liệu này chứa các bản ghi vi phạm ràng buộc khóa ngoại. Có thể dữ liệu này loại trừ các hàng đã được thêm vào bảng nhưng chưa được cam kết.

Bạn thực sự không có cách nào để biết trạng thái của dữ liệu là gì.

Nếu bạn đang cố gắng lấy những thứ như Count Row hoặc dữ liệu tóm tắt khác, một số lỗi có thể chấp nhận được, thì NOLOCK là một cách hay để tăng hiệu suất cho các truy vấn này và tránh chúng tác động tiêu cực đến hiệu suất cơ sở dữ liệu.

Luôn sử dụng gợi ý NOLOCK thận trọng và xử lý mọi dữ liệu mà nó trả về đáng ngờ.

+0

Cảm ơn. Đây là những gì tôi đã giả định nhưng đã được hỏi về nó bởi một đồng nghiệp và nghiên cứu ban đầu của tôi làm cho tôi câu hỏi bản thân mình. Tài liệu SQLServer 2005 nói rằng với NOLOCK là lược đồ khóa mặc định cho tất cả các câu lệnh chọn! Tôi đoán sau đó gợi ý của tôi sẽ là thừa trong ... –

+2

... 2005 và không có bất kỳ ảnh hưởng nào. Chúng tôi đang chạy 2000 ngay bây giờ (nhờ nhà cung cấp của chúng tôi) và không có tuyên bố tương tự trong tài liệu. –

+4

Bạn của bạn cần đọc tài liệu. Bảng Gợi ý (Giao dịch-SQL) http://msdn.microsoft.com/en-us/library/ms187373(SQL.90).aspx –

7

Nó sẽ nhanh hơn bởi vì nó không phải chờ ổ khóa

+0

Nhanh hơn bao nhiêu? Bạn có thể cung cấp bất kỳ số cải thiện tốc độ nào không? –

+4

"Số tiền" phụ thuộc vào những gì bạn đang làm cụ thể với dữ liệu của mình và thời gian bạn thường phải đợi để mua lại khóa. – StingyJack

+0

Điểm chuẩn chính xác duy nhất là điểm chuẩn bạn tạo và tự chạy. Những gì mọi người nói với bạn là tốt như "kiểm tra là trong thư". Tôi đã chứng minh nhiều huyền thoại và giả định sai nhiều lần bằng cách chạy điểm chuẩn của riêng mình. – TravisO

58

NOLOCK làm cho hầu hết các câu lệnh SELECT nhanh hơn, do thiếu khóa chia sẻ. Ngoài ra, việc thiếu các ổ khóa có nghĩa là các nhà văn sẽ không bị cản trở bởi lệnh SELECT của bạn.

NOLOCK có chức năng tương đương với mức độc lập READ UNCOMMITTED. Sự khác biệt chính là bạn có thể sử dụng NOLOCK trên một số bảng nhưng không sử dụng NOLOCK, nếu bạn chọn. Nếu bạn dự định sử dụng NOLOCK trên tất cả các bảng trong một truy vấn phức tạp, thì sử dụng SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED sẽ dễ dàng hơn, bởi vì bạn không phải áp dụng gợi ý cho mỗi bảng.

Dưới đây là thông tin về tất cả các mức cách ly theo ý của bạn, cũng như các gợi ý bảng.

SET TRANSACTION ISOLATION LEVEL

Table Hint (Transact-SQL)

+1

Tôi đồng ý, nhưng không hoàn toàn; điều quan trọng là chỉ ra rằng một gợi ý KHÔNG LOCK/ĐỌC UNCOMMITTED không thực sự cải thiện tốc độ truy vấn, nhưng nhiều hơn như vậy làm cho nó xuất hiện nhanh hơn bởi vì nó không phải chờ đợi cho các truy vấn trước đó để hoàn thành. Vì vậy, thực sự, truy vấn SEEMS nhanh hơn, thay vì IS nhanh hơn (tôi nghĩ). –

+0

@BorhanMooz Vâng, có khoản tiết kiệm không phải yêu cầu khóa từ trình quản lý khóa. Ngay cả khi không có các truy vấn khác chờ đợi, điều này có chi phí và chi phí bộ nhớ. –

+1

Tôi đã thảo luận vấn đề này với một số bạn đồng nghiệp của tôi. Như tôi đã hiểu, một truy vấn sử dụng một gợi ý WITH (NOLOCK) vẫn yêu cầu một khóa Schema-Shared để đạt được (http://www.mssqltips.com/sqlservertip/2470/understanding-the-sql-server-nolock-hint /). –

2
  • SELECT hiện tại sẽ bắt đầu sớm hơn, bởi vì nó không phải chờ đợi.

  • Các giao dịch khác sẽ chậm lại vì giờ đây họ đang chia sẻ thời gian xử lý của họ với một giao dịch mới.

Không sử dụng.

NOLOCK thường được khai thác như một cách kỳ diệu để tăng tốc độ đọc cơ sở dữ liệu, nhưng tôi cố gắng tránh sử dụng nó bất cứ khi nào có thể.

Tập kết quả có thể chứa các hàng chưa được cam kết, thường sau đó được cuộn lại.

Lỗi hoặc tập kết quả có thể trống, thiếu hàng hoặc hiển thị cùng một hàng nhiều lần.

Điều này là do các giao dịch khác đang di chuyển dữ liệu cùng lúc bạn đọc dữ liệu đó.

ĐỌC KẾT THÚC thêm một vấn đề khác trong đó dữ liệu bị hỏng trong một cột duy nhất nơi nhiều người dùng thay đổi cùng một ô cùng một lúc.

Ngoài ra còn có các tác dụng phụ khác, dẫn đến hy sinh tốc độ tăng mà bạn hy vọng đạt được ngay từ đầu.

Bây giờ bạn đã biết, không bao giờ sử dụng lại.

Các vấn đề liên quan