Ảnh hưởng của gợi ý NOLOCK trong các câu lệnh CHỌN


199

Tôi đoán câu hỏi thực sự là:

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

  1. câu lệnh CHỌN hiện tại
  2. các giao dịch khác so với bảng đã cho

Thí dụ:

Select * 
from aTable with (NOLOCK)

3
Những câu trả lời SODBA này rõ ràng hơn một chút về những gì đang thực sự xảy ra.
Đã xem

Câu trả lời:


289

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

2) , một lựa chọn với NOLOCKsẽ 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 so với lựa chọn thông thường.

Tại sao điều này sẽ được?

NOLOCKthông thường (tùy thuộc vào công cụ DB của bạn) có nghĩa là cung cấp cho tôi dữ liệu của bạn và tôi không quan tâm nó đang ở trạng thái nào và đừng bận tâm giữ nó trong khi bạn đọc từ đó. Tất cả cùng một lúc nhanh hơn, ít tốn tài nguyên hơ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ỳ điều gì quan trọng của hệ thống hoặc khi yêu cầu tính chính xác tuyệt đối khi sử dụng dữ liệu có nguồn gốc từ một lần NOLOCKđọc. Hoàn toàn có thể là dữ liệu này chứa các hàng đã bị xóa trong quá trình 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 các 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 để có được những thứ như Đếm hàng hoặc dữ liệu tóm tắt khác trong đó có thể chấp nhận được một số lỗi, thì đó NOLOCKlà cách tốt để tăng hiệu suất cho các truy vấn này và tránh để chúng ảnh hưởng tiêu cực đến hiệu suất cơ sở dữ liệu.

Luôn luôn sử dụng NOLOCKgợi ý một cách thận trọng và xử lý mọi dữ liệu mà nó trả lại một cách đáng ngờ.


Cảm ơn. Đây là những gì tôi đã giả định nhưng đã được một đồng nghiệp đặt câu hỏi về nó và nghiên cứu ban đầu của tôi khiến tôi tự đặt câu hỏi. 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 được chọn! Tôi đoán sau đó những gợi ý của tôi sẽ là dư thừa trong ...
Bob Probst

2
... 2005 và không có tác dụng. 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.
Bob Probst

4
Bạn của bạn cần đọc tài liệu. Bảng Gợi ý (Transact-SQL) msdn.microsoft.com/en-us/l Library / ms187373 (MySQL.90
Pittsburgh DBA

9
Lưu ý bên lề: nếu điều này là đúng, nó sẽ là sự hỗn loạn tuyệt đối.
Pittsburgh DBA

1
Điểm 1 và 2 cần được giới hạn ở 1) "... khi một hành động chèn / cập nhật / xóa đang chờ xử lý trên bảng ." và 2) "... sẽ cho phép chèn / cập nhật / xóa truy vấn đối với ...". Tôi sẽ (ưu tiên cá nhân) thay đổi các trường hợp "nhanh hơn" thành "sớm hơn" vì sự khác biệt đang chờ quá trình khác hoàn thành.
Đã xem

61

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

NOLOCK có chức năng tương đương với mức cô lập ĐỌC KHÔNG HOÀN THÀNH. 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 phải bảng khác, nếu bạn chọn. Nếu bạn có kế hoạch sử dụng NOLOCK trên tất cả các bảng trong một truy vấn phức tạp, thì việc sử dụng SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED sẽ dễ dàng hơn, 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ô lập theo ý của bạn, cũng như gợi ý về bảng.

THIẾT LẬP CẤP PHÂN TÍCH GIAO DỊCH

Gợi ý bảng (Giao dịch-SQL)


2
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 / READ UNCOMMITTED không thực sự cải thiện tốc độ của truy vấn, nhưng hơn nữa làm cho nó xuất hiện nhanh hơn vì không phải đợi các truy vấn trước hoàn thành. Vì vậy, thực sự, truy vấn SEEMS nhanh hơn, chứ không phải IS nhanh hơn (tôi nghĩ).
Möoz

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

1
Tôi đã thảo luận điều này với một số đồng nghiệp của tôi. Theo tôi hiểu, một truy vấn sử dụng gợi ý VỚI (NOLOCK) vẫn yêu cầu khóa Schema-Shared phải đạt được ( mssqltips.com/sqlservertip/2470/ .)
Möoz

1
Có, nhưng không phải hàng ngàn khóa được chia sẻ trên các trang hoặc phạm vi. Một khóa Schema là MỘT khóa, không phải THOUSANDS. Nếu chúng ta muốn trở thành người phạm tội, chúng ta có thể tiếp tục tranh luận về vấn đề này, nhưng đúng vậy, sẽ có một lượng tối thiểu khóa trên đầu. Các khoản tiết kiệm là đáng kể. Làm toán trên này: msdn.microsoft.com/en-us/l Library / aa337559 (v = sql.100) .aspx
Pittsburgh DBA


6

Nó sẽ nhanh hơn vì không phải đợi khóa


Nhanh hơn bao nhiêu? Bạn có thể cung cấp bất kỳ số cải thiện tốc độ?
Eugeniu Torica

5
"Bao nhiêu" tùy 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 chờ để mua lại khóa.
StingyJack

Điểm chuẩn chính xác duy nhất là điểm bạn tự tạo và tự chạy. Những gì mọi người nói với bạn cũng tốt như "séc có 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 tôi.
TravisO

^ @TravisO - hoàn toàn chính xác. Tôi đã thực hiện NOLOCK chậm hơn một vài lần. Không hoàn toàn chắc chắn tại sao, nhưng tôi đang sử dụng điều đó khi khắc phục sự cố và tôi không muốn ảnh hưởng tiêu cực (quá mức) đến sản xuất
StingyJack

2
  • Câu trả lời là nếu truy vấn được chạy nhiều lần cùng một lúc, vì mỗi giao dịch sẽ không cần đợi các giao dịch khác hoàn thành. Tuy nhiên, nếu truy vấn được tự chạy một lần thì câu trả lời là Không.

  • . Có một xác suất đáng kể rằng việc sử dụng cẩn thận VỚI (NOLOCK) sẽ tăng tốc tổng thể cơ sở dữ liệu của bạn. Điều đó có nghĩa là các giao dịch khác sẽ không phải đợi câu lệnh CHỌN này kết thúc, nhưng mặt khác, các giao dịch khác sẽ chậm lại vì hiện tại chúng đang chia sẻ thời gian xử lý của chúng với một giao dịch mới.

Hãy cẩn thận chỉ sử dụng WITH (NOLOCK)trong các câu lệnh CHỌN trên các bảng có chỉ mục được nhóm.

VỚI (NOLOCK) thường được khai thác như một cách kỳ diệu để tăng tốc độ giao dịch đọc cơ sở dữ liệu.

Tập kết quả có thể chứa các hàng chưa được cam kết, thường được khôi phục sau đó.

Nếu VỚI (NOLOCK) được áp dụng cho bảng có chỉ mục không được nhóm thì chỉ mục hàng có thể được thay đổi bởi các giao dịch khác khi dữ liệu hàng đang được truyền vào bảng kết quả. Điều này có nghĩa là tập kết quả có thể thiếu các hàng hoặc hiển thị cùng một hàng nhiều lần.

ĐỌC CAM KẾT thêm một vấn đề bổ sung trong đó dữ liệu bị hỏng trong một cột trong đó nhiều người dùng thay đổi cùng một ô.

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.