Là NOLOCK (gợi ý máy chủ Sql) thực hành xấu?


125

Tôi đang kinh doanh trong việc tạo ra trang web và các ứng dụng không phải là nhiệm vụ quan trọng -> vd. phần mềm ngân hàng, chuyến bay vũ trụ, ứng dụng giám sát chăm sóc chuyên sâu, vv Bạn có ý tưởng.

Vì vậy, với sự từ chối lớn đó, việc sử dụng gợi ý NOLOCK trong một số câu lệnh Sql có tệ không? Một số năm trước, một Quản trị viên Sql đã đề nghị rằng tôi nên sử dụng NOLOCK nếu tôi hài lòng với "đọc bẩn" sẽ mang lại cho tôi hiệu suất cao hơn một chút trong hệ thống của mình vì mỗi lần đọc không khóa bảng / hàng / bất cứ điều gì.

Tôi cũng được cho biết rằng đó là một giải pháp tuyệt vời nếu tôi gặp phải tình trạng khóa chết. Vì vậy, tôi đã bắt đầu theo suy nghĩ đó trong một vài năm cho đến khi một bậc thầy về Sql đang giúp tôi với một số mã ngẫu nhiên và nhận thấy tất cả các NOLOCKS trong mã sql của tôi. Tôi đã bị mắng một cách lịch sự và anh ấy đã cố gắng giải thích cho tôi (tại sao đó không phải là một điều tốt) và tôi đã bị lạc. Tôi cảm thấy rằng bản chất của lời giải thích của anh ấy là 'đó là một giải pháp hỗ trợ ban nhạc cho một vấn đề nghiêm trọng hơn .. đặc biệt là nếu bạn đang gặp bế tắc. Như vậy, khắc phục gốc rễ của vấn đề '.

Tôi đã làm một số googling gần đây về nó và tình cờ thấy bài này .

Vì vậy, một số sql db guru có thể làm ơn khai sáng cho tôi không?


Tôi không hiểu Sam, bạn đang nói sử dụng cách ly Snapshot nếu đó là một trang web đọc nhiều. Nhưng sau đó bạn đang nói SO đã làm điều đó, và nó có tệ không? hoặc chỉ sử dụng NOLOCK của họ?
Pure.Krom

Câu trả lời:


67

Với gợi ý NOLOCK, mức cô lập giao dịch cho SELECTcâu lệnh là READ UNCOMMITTED. Điều này có nghĩa là truy vấn có thể thấy dữ liệu bẩn và không nhất quán.

Đây không phải là một ý tưởng tốt để áp dụng như một quy tắc. Ngay cả khi hành vi đọc bẩn này vẫn ổn đối với ứng dụng dựa trên web quan trọng của bạn, việc quét NOLOCK có thể gây ra lỗi 601 sẽ chấm dứt truy vấn do di chuyển dữ liệu do thiếu bảo vệ khóa.

Tôi khuyên bạn nên đọc khi Cách ly ảnh chụp giúp và khi nó đau - MSDN khuyên bạn nên sử dụng READ CAMED SNAPSHOT thay vì SNAPSHOT trong hầu hết các trường hợp.


1
Rex, xin vui lòng thêm một lưu ý về cách ly ảnh chụp nhanh.
Sam Saffron

2
Vâng, Sam đang nói cách ly Ảnh chụp nhanh và bạn đang đề xuất Đọc Ảnh chụp đã cam kết. Tôi đang rất bối rối: P (và tôi cũng chưa đi sâu vào các bài báo!)
Pure.Krom

2
Nó đôi khi hữu ích, nhưng thường không cho sản xuất. Tôi sử dụng nó thường xuyên để lấy ra một mẫu dữ liệu để kiểm tra hoặc để tạo các báo cáo mà tôi chủ yếu quan tâm đến thứ tự độ lớn trong đó việc đọc bẩn sẽ không thành vấn đề.
TimothyAWiseman

NOLOCK == Tôi không quan tâm nếu các hàng đã cam kết bị bỏ lỡ, các hàng không được cam kết được bao gồm, trong các trường hợp hiếm hoi, cùng một hàng được trả lại nhiều lần và trong các trường hợp rất hiếm, các hàng được trả lại không khớp với truy vấn của tôi. (xem blogs.msdn.com/b/sqlcat/archive/2007/02/01/... , tìm thấy từ một q'n SO về chủ đề này)
Andrew Hill

106

Trước khi làm việc với Stack Overflow, tôi đã phản đối NOLOCKhiệu trưởng rằng bạn có khả năng thực hiện SELECTvới NOLOCKvà lấy lại kết quả với dữ liệu có thể đã lỗi thời hoặc không nhất quán. Một yếu tố cần suy nghĩ là có bao nhiêu bản ghi có thể được chèn / cập nhật cùng lúc một quá trình khác có thể được chọn dữ liệu từ cùng một bảng. Nếu điều này xảy ra rất nhiều thì có khả năng cao là bế tắc trừ khi bạn sử dụng chế độ cơ sở dữ liệu như READ COMMITED SNAPSHOT.

Kể từ đó, tôi đã thay đổi quan điểm của mình về việc sử dụng NOLOCKsau khi chứng kiến ​​cách nó có thể cải thiện SELECThiệu suất cũng như loại bỏ các bế tắc trên SQL Server được tải ồ ạt. Đôi khi bạn có thể không quan tâm rằng dữ liệu của mình không được cam kết chính xác 100% và bạn cần nhanh chóng lấy lại kết quả mặc dù chúng có thể bị lỗi thời.

Tự hỏi bản thân một câu hỏi khi nghĩ đến việc sử dụng NOLOCK:

Có phải truy vấn của tôi bao gồm một bảng có số lượng INSERT/ UPDATElệnh cao và tôi có quan tâm nếu dữ liệu được trả về từ một truy vấn có thể thiếu những thay đổi này tại một thời điểm nhất định không?

Nếu câu trả lời là không, thì hãy sử dụng NOLOCKđể cải thiện hiệu suất.


Tôi vừa thực hiện tìm kiếm nhanh NOLOCKtừ khóa trong cơ sở mã cho Stack Overflow và tìm thấy 138 trường hợp, vì vậy chúng tôi sử dụng nó ở một vài nơi.


7
IMO, Đây là một chút đơn giản. Bế tắc có thể được loại bỏ bằng cách sử dụng các chỉ số che phủ, giảm áp lực khỏi chỉ số Clustered.
Mitch Wheat

8
Tôi không muốn làm giảm tầm quan trọng của bảo hiểm chỉ số tốt. Đôi khi các truy vấn sử dụng NOLOCK có thể thêm hiệu suất bổ sung trên mức tăng được nhận ra bởi các chỉ mục trên các bảng có số lượng chèn / cập nhật cao. Tốc độ truy vấn trên Stack Overflow là tối quan trọng ngay cả với chi phí dữ liệu không chính xác hoặc bị thiếu.
Geoff Dalgas

9
Rõ ràng người ta có thể nhận được các hàng trùng lặp bằng cách sử dụng NOLOCK. Điều này có nghĩa là tôi phải downvote câu trả lời của bạn. Lấy làm tiếc.
ErikE

1
@MitchWheat A SELECT, chỉ đọc từ một chỉ số bao phủ, có thể gây ra bế tắc. SPID 1) bắt đầu a SELECTtừ chỉ số bao phủ. SPID 2) Bắt đầu một UPDATEbảng. Cập nhật sau đó chuyển sang cập nhật chỉ số bao phủ. UPDATEđạt đến một phạm vi chỉ số bị khóa bởi SELECTvà bị chặn. SPID 1) vẫn đang tìm kiếm thông qua chỉ số bao phủ, tìm thấy một phạm vi bị khóa bởi UPDATEvà bị chặn. CHẾT . Không có gì có thể giải quyết bế tắc đó (ngoại trừ bắt lỗi SQL Server 1205 và tự động thử lại hoặc sử dụng NOLOCK)
Ian Boyd

2
Tôi nghĩ rằng điều quan trọng cần lưu ý về câu trả lời này là nó phù hợp với vấn đề hiện tại . Tùy thuộc vào ứng dụng của bạn, nguy cơ dữ liệu cũ / không được cam kết / trùng lặp / thiếu có thể không đáng để đánh đổi.
Nhà phát triển toàn diện

20

Nếu bạn không quan tâm đến việc đọc bẩn (nghĩa là trong tình huống chủ yếu là ĐỌC), thì NOLOCKtốt thôi.

NHƯNG , lưu ý rằng phần lớn các sự cố khóa là do không có chỉ mục 'chính xác' cho khối lượng công việc truy vấn của bạn (giả sử phần cứng phụ thuộc vào nhiệm vụ).

Và lời giải thích của guru là chính xác. Nó thường là một giải pháp hỗ trợ ban nhạc cho một vấn đề nghiêm trọng hơn.

Chỉnh sửa : Tôi chắc chắn không gợi ý rằng NOLOCK nên được sử dụng. Tôi đoán tôi nên đã làm điều đó rõ ràng rõ ràng. (Tôi sẽ chỉ sử dụng nó, trong những trường hợp khắc nghiệt mà tôi đã phân tích rằng nó ổn). NHƯ một ví dụ, một thời gian trước tôi đã làm việc với một số TSQL đã được rắc NOLOCK để thử và giảm bớt các vấn đề về khóa. Tôi đã loại bỏ tất cả, thực hiện các chỉ mục chính xác và TẤT CẢ các bế tắc đã biến mất.


3
Hmm .. tôi vẫn không nhận được nó. Vì vậy, nó ổn, nhưng nó cũng là hình thức kém .. đó là những gì bạn đang nói?
Pure.Krom

Giả định rằng bạn KHÔNG BAO GIỜ quan tâm đến việc đọc bẩn, thì nó sẽ không bị tổn thương. NHƯNG đó thường là một trường hợp điều trị triệu chứng và không phải là nguyên nhân ...
Mitch Wheat

2
Chà, tôi không nghĩ rằng rexem công bằng của nó chỉ bị hạ cấp, tôi nghĩ rằng bạn đã không giải quyết các lỗi tùy ý chỉ nổi lên khi bạn sử dụng nolock. Thỉnh thoảng để có một trang lỗi trống trên trang web của bạn, nó thực sự là hình thức kém. Tôi không thích khẳng định rằng "nếu bạn không quan tâm đến việc đọc bẩn thì không sao cả" ... nó không ổn, ngay cả khi bạn không quan tâm đến việc đọc bẩn
Sam Saffron

Trang trống bạn nhận được khi truy vấn tạo ngoại lệ mà bạn không triển khai thử lại logic. Điều gì xảy ra trên các trang web của bạn khi kết quả thực hiện truy vấn có ngoại lệ, bạn có thử lại logic ở mọi nơi không?
Sam Saffron

Thực hiện một truy vấn được tối ưu hóa rất tốt mà bạn biết là đang đánh các chỉ mục thích hợp. Sau đó thêm gợi ý nolock và xem nó nhanh hơn. Nếu bạn không quan tâm đến việc đọc bẩn, bạn sẽ không bao giờ làm tổn thương chính mình khi sử dụng nolock.
Phần cứng

13

Nghi ngờ đó là một "bậc thầy", người đã có bất kỳ kinh nghiệm nào về lưu lượng truy cập cao ...

Các trang web thường "bẩn" vào thời điểm người đó đang xem trang được tải hoàn toàn. Hãy xem xét một hình thức tải từ cơ sở dữ liệu và sau đó lưu dữ liệu đã được chỉnh sửa ?? Thật ngu ngốc khi mọi người tiếp tục đọc những thứ bẩn thỉu như vậy là không.

Điều đó nói rằng, nếu bạn có một số lớp xây dựng trên các lựa chọn của mình, bạn có thể đang xây dựng trong tình trạng dư thừa nguy hiểm. Nếu bạn đang xử lý các tình huống về tiền hoặc trạng thái, thì bạn không chỉ cần đọc / ghi dữ liệu giao dịch, mà còn là một giải pháp tương tranh thích hợp (điều mà hầu hết các "bậc thầy" không bận tâm).

Mặt khác, nếu bạn có một tìm kiếm sản phẩm nâng cao cho một trang web (nghĩa là một cái gì đó có khả năng sẽ không được lưu trong bộ nhớ cache và hơi chuyên sâu) và bạn đã từng xây dựng một trang web có nhiều hơn một vài người dùng (phenominal có bao nhiêu "Các chuyên gia" chưa), thật là kỳ quặc khi chai cổ mọi quá trình khác đằng sau nó.

Biết ý nghĩa của nó và sử dụng nó khi thích hợp. Cơ sở dữ liệu của bạn hầu như sẽ luôn là cổ chai chính của bạn trong những ngày này và việc thông minh về việc sử dụng NOLOCK có thể giúp bạn tiết kiệm hàng ngàn cơ sở hạ tầng.

EDIT: Nó không chỉ là những bế tắc mà nó còn giúp, mà còn là bạn sẽ khiến mọi người khác chờ đợi cho đến khi bạn hoàn thành, hoặc ngược lại.

Sử dụng NOLOCK Gợi ý trong EF4?


10

Không có câu trả lời nào là sai, tuy nhiên có thể hơi khó hiểu.

  • Khi truy vấn các giá trị / hàng đơn lẻ, việc sử dụng NOLOCK luôn là điều không tốt - bạn có thể không bao giờ muốn hiển thị thông tin không chính xác hoặc thậm chí có thể thực hiện bất kỳ hành động nào đối với dữ liệu không chính xác.
  • Khi hiển thị thông tin thống kê thô, NOLOCK có thể rất hữu ích. Lấy SO làm ví dụ: Sẽ là vô nghĩa khi lấy khóa để đọc số lượt xem chính xác của câu hỏi hoặc số câu hỏi chính xác cho thẻ. Không ai quan tâm nếu bạn nêu không chính xác 3360 câu hỏi được gắn thẻ "máy chủ sql" và vì quay lại giao dịch, 3359 câu hỏi một giây sau.

Tôi không đồng ý với điểm đầu tiên của bạn cả. NẾU bạn đang truy vấn các giá trị / hàng đơn lẻ và bạn đang chỉ định một id duy nhất cho hàng đó và bạn biết rằng không có quá trình nào khác sẽ truy cập vào nó, thì việc sử dụng nolock là hoàn toàn chấp nhận được và giảm việc chặn trong một ứng dụng đồng thời.
tuseau

1
Không, không phải vậy. Hàng có thể thay đổi vì các lý do khác, ví dụ: chèn một hàng khác sẽ chia trang. Lập chỉ mục thích hợp, Đọc ảnh chụp được cam kết và Cách ly ảnh chụp hầu như luôn là những ý tưởng tốt hơn.
Mark Sowul

1
@tuseau nếu bạn "biết" rằng sẽ không có quá trình nào khác truy cập vào hàng, hành động lấy khóa sẽ không chặn bất cứ thứ gì, vì vậy, chi phí của bạn (thực tế) không có gì,
Andrew Hill

2

Là một nhà phát triển chuyên nghiệp, tôi muốn nói rằng nó phụ thuộc. Nhưng tôi chắc chắn làm theo lời khuyên của GATS và OMG Ponies. Biết những gì bạn đang làm, biết khi nào nó giúp và khi nào nó đau và

đọc gợi ý và những ý tưởng nghèo nàn khác

những gì có thể làm cho bạn hiểu máy chủ sql sâu hơn. Tôi thường tuân theo quy tắc rằng Gợi ý SQL là EVIL, nhưng không may là tôi sử dụng chúng mọi lúc và sau đó khi tôi chán ngấy với việc buộc máy chủ SQL làm những việc ... Nhưng đây là những trường hợp hiếm gặp.

luke


2

Khi bộ phận hỗ trợ ứng dụng muốn trả lời các truy vấn quảng cáo từ máy chủ sản xuất bằng SSMS (không phục vụ cho báo cáo), tôi đã yêu cầu họ sử dụng nolock. Bằng cách đó, việc kinh doanh 'chính' không bị ảnh hưởng.


2

Tôi đồng ý với một số ý kiến ​​về gợi ý của NOLOCK và đặc biệt với những người nói rằng "hãy sử dụng nó khi thích hợp". Nếu ứng dụng viết kém và sử dụng đồng thời cách không phù hợp - điều đó có thể gây ra sự leo thang khóa. Bảng giao dịch cao cũng đang bị khóa mọi lúc do tính chất của chúng. Có phạm vi bảo hiểm chỉ số tốt sẽ không giúp lấy lại dữ liệu, nhưng đặt CẤP ĐỘ CẤP để ĐỌC B UNNG KHÔNG. Ngoài ra tôi tin rằng việc sử dụng gợi ý NOLOCK là an toàn trong nhiều trường hợp khi bản chất của các thay đổi là có thể dự đoán được. Ví dụ: trong sản xuất khi các công việc với khách du lịch đang trải qua các quy trình khác nhau với nhiều phép đo, bạn có thể thực hiện truy vấn một cách an toàn với công việc đã hoàn thành với gợi ý NOLOCK và cách này tránh va chạm với các phiên khác đặt các khóa KHUYẾN MÃI hoặc ĐỘC QUYỀN trên bàn /trang. Dữ liệu bạn truy cập trong trường hợp này là tĩnh, nhưng nó có thể nằm trong một bảng rất giao dịch với hàng trăm triệu bản ghi và hàng nghìn cập nhật / chèn mỗi phút. Chúc mừng


2

Tôi tin rằng hầu như không bao giờ đúng khi sử dụng nolock.

Nếu bạn đang đọc một hàng đơn, thì chỉ mục chính xác có nghĩa là bạn sẽ không cần NOLOCK vì các hành động hàng riêng lẻ được hoàn thành nhanh chóng.

Nếu bạn đang đọc nhiều hàng cho bất cứ thứ gì ngoài màn hình tạm thời và quan tâm đến việc có thể lặp lại kết quả hoặc bảo vệ bằng số được tạo ra, thì NOLOCK không phù hợp.

NOLOCK là một thẻ thay thế cho "tôi không quan tâm nếu câu trả lời này có chứa các hàng trùng lặp, các hàng bị xóa hoặc các hàng không bao giờ được chèn để bắt đầu vì rollback"

Các lỗi có thể xảy ra theo NOLOCK:

  • Hàng phù hợp mà không được trả lại ở tất cả.
  • các hàng đơn được trả về nhiều lần (bao gồm nhiều phiên bản của cùng một khóa chính)
  • Hàng không khớp được trả lại.

Bất kỳ hành động nào có thể gây ra sự phân tách trang trong khi chọn noLock đang chạy có thể khiến những điều này xảy ra. Hầu như bất kỳ hành động nào (thậm chí xóa) có thể gây ra sự phân chia trang.

Do đó: nếu bạn "biết" rằng hàng sẽ không bị thay đổi trong khi bạn đang chạy, đừng sử dụng nolock, vì một chỉ mục sẽ cho phép truy xuất hiệu quả.

Nếu bạn nghi ngờ hàng có thể thay đổi trong khi truy vấn đang chạy và bạn quan tâm đến độ chính xác, đừng sử dụng nolock.

Nếu bạn đang xem xét NOLOCK vì các bế tắc, hãy kiểm tra cấu trúc kế hoạch truy vấn để quét bảng bất ngờ, theo dõi các bế tắc và xem tại sao chúng xảy ra. NOLOCK xung quanh việc ghi có thể có nghĩa là các truy vấn mà trước đó bị bế tắc sẽ có khả năng cả hai viết sai câu trả lời.


2

Các giải pháp tốt hơn, khi có thể là:

  • Sao chép dữ liệu của bạn (sử dụng sao chép nhật ký) vào cơ sở dữ liệu báo cáo.
  • Sử dụng ảnh chụp nhanh SAN và gắn phiên bản nhất quán của DB
  • Sử dụng cơ sở dữ liệu có mức cô lập giao dịch cơ bản tốt hơn

Mức cô lập giao dịch SNAPSHOT đã được tạo vì MS đang mất doanh số cho Oracle. Oracle sử dụng nhật ký hoàn tác / làm lại để tránh vấn đề này. Postgres sử dụng MVCC. Trong tương lai, Heckaton của MS sẽ sử dụng MVCC, nhưng còn nhiều năm nữa mới sẵn sàng sản xuất.


Có một lỗi đánh máy ở trên. Ý tôi là nói "cơ chế cách ly giao dịch cơ bản tốt hơn".
pwy

1
Mức cô lập giao dịch SNAPSHOT là phát minh của MS. Về cơ bản, nó đặt dữ liệu vào một bảng tạm thời trong TEMPDB. DB đó được chia sẻ giữa tất cả các DB trên hộp. Vì vậy, bạn sẽ muốn sử dụng SSD cho TEMPDB khi có thể. Đó có lẽ là nỗ lực ít hơn so với các tùy chọn khác.
pwy

1

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 được khôi phục sau đó.

Một lỗi hoặc tập kết quả có thể trống, bị thiếu các 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 đang đọc 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 ô.


-2

Trong cuộc sống thực, nơi bạn bắt gặp các hệ thống đã được viết và thêm chỉ mục vào các bảng sau đó làm chậm quá trình tải dữ liệu của bảng dữ liệu 14gig, đôi khi bạn buộc phải sử dụng VỚI NOLOCK trên các báo cáo của mình và kết thúc tháng để tổng hợp , đếm, v.v.) không làm hàng, trang, khóa bảng và làm giảm hiệu suất tổng thể. Nói một cách dễ dàng trong một hệ thống mới không bao giờ sử dụng VỚI NOLOCK và sử dụng các chỉ mục - nhưng việc thêm các chỉ mục làm giảm nghiêm trọng việc tải dữ liệu, và khi đó tôi đã nói, thay đổi cơ sở mã để xóa các chỉ mục, sau đó tải hàng loạt sau đó tạo lại các chỉ mục - tất cả đều tốt và tốt, nếu bạn đang phát triển một hệ thống mới. Nhưng không phải khi bạn đã có một hệ thống.


1
bạn đang nói gì
Max Alexander Hanna
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.