THIẾT LẬP NOCOUNT khi sử dụng


341

Lấy cảm hứng từ câu hỏi này , nơi có các quan điểm khác nhau về SET NOCOUNT ...

Chúng ta có nên sử dụng SET NOCOUNT ON cho SQL Server không? Nếu không, tai sao không?

Nó làm gì Chỉnh sửa 6, vào ngày 22 tháng 7 năm 2011

Nó chặn thông báo "xx hàng bị ảnh hưởng" sau bất kỳ DML nào. Đây là một tập kết quả và khi được gửi, khách hàng phải xử lý nó. Nó nhỏ, nhưng có thể đo lường được (xem câu trả lời bên dưới)

Đối với các kích hoạt, v.v., khách hàng sẽ nhận được nhiều "hàng xx bị ảnh hưởng" và điều này gây ra tất cả các lỗi cho một số ORM, MS Access, JPA, v.v. (xem các chỉnh sửa bên dưới)

Lý lịch:

Thực tiễn tốt nhất được chấp nhận chung (tôi nghĩ cho đến khi câu hỏi này) là sử dụng SET NOCOUNT ONtrong các trình kích hoạt và các thủ tục được lưu trữ trong SQL Server. Chúng tôi sử dụng nó ở mọi nơi và google nhanh chóng cho thấy rất nhiều MVP của SQL Server cũng đồng ý.

MSDN cho biết điều này có thể phá vỡ một SQLDataAd CHƯƠNG .net .

Bây giờ, điều này có nghĩa với tôi rằng SQLDataAd CHƯƠNG bị giới hạn trong việc xử lý CRUD hoàn toàn đơn giản vì nó hy vọng thông điệp "n hàng bị ảnh hưởng" khớp. Vì vậy, tôi không thể sử dụng:

  • NẾU EXISTS để tránh trùng lặp (không có thông báo ảnh hưởng đến hàng) Lưu ý: sử dụng thận trọng
  • Ở ĐÂU KHÔNG EXISTS (ít hàng hơn dự kiến
  • Lọc ra các cập nhật nhỏ (ví dụ: không có dữ liệu thực sự thay đổi)
  • Thực hiện bất kỳ truy cập bảng trước (chẳng hạn như đăng nhập)
  • Ẩn sự phức tạp hoặc biến dạng
  • Vân vân

Trong câu hỏi marc_s (người biết công cụ SQL của anh ta) nói không sử dụng nó. Điều này khác với những gì tôi nghĩ (và tôi cũng tự coi mình là người có năng lực ở SQL).

Có thể tôi đang thiếu một cái gì đó (cứ thoải mái chỉ ra điều hiển nhiên), nhưng bạn nghĩ sao?

Lưu ý: đã nhiều năm kể từ khi tôi gặp lỗi này vì hiện tại tôi không sử dụng SQLDataAd CHƯƠNG.

Chỉnh sửa sau khi nhận xét và câu hỏi:

Chỉnh sửa: Thêm suy nghĩ ...

Chúng tôi có nhiều khách hàng: một người có thể sử dụng C # SQLDataAdaptor, một người khác có thể sử dụng nHibernate từ Java. Đây có thể bị ảnh hưởng theo những cách khác nhau với SET NOCOUNT ON.

Nếu bạn coi các procs được lưu trữ như các phương thức, thì đó là hình thức xấu (chống mẫu) để cho rằng một số xử lý nội bộ hoạt động theo một cách nhất định cho mục đích riêng của bạn.

Chỉnh sửa 2: kích hoạt phá vỡ câu hỏi nHibernate , nơi SET NOCOUNT ONkhông thể được đặt

(và không, nó không phải là một bản sao của điều này )

Chỉnh sửa 3: Thông tin thêm, nhờ đồng nghiệp MVP của tôi

Chỉnh sửa 4: 13 tháng 5 năm 2011

Phá vỡ Linq 2 SQL quá khi không được chỉ định?

Chỉnh sửa 5: 14 tháng 6 năm 2011

Phá vỡ JPA, Proc được lưu trữ với các biến bảng: JPA 2.0 có hỗ trợ các biến bảng SQL Server không?

Chỉnh sửa 6: 15 tháng 8 năm 2011

Lưới dữ liệu "Chỉnh sửa hàng" SSMS yêu cầu THIẾT LẬP NOCOUNT: Cập nhật kích hoạt với GROUP BY

Chỉnh sửa 7: 07/03/2013

Thông tin chi tiết chuyên sâu từ @RemusRusanu:
Liệu SET NOCOUNT ON có thực sự tạo ra sự khác biệt lớn về hiệu suất không


@AlexKuznetsov: Cách tiếp cận "Chủ đề an toàn" sẽ là gì? Chắc chắn các bài đọc được thực hiện trong EXISTS vẫn sẽ được bao gồm bất kỳ giao dịch nổi bật nào?
AnthonyWJones

2
@Jeremy Seghi: xin lỗi vì đã trả lời trễ. Thông báo (# mũi tên bị ảnh hưởng) là một công cụ máy khách được SSMS diễn giải, v.v .: tuy nhiên có một gói được gửi với thông tin này. Tất nhiên, tôi biết cách @@ rowcount hoạt động, v.v., nhưng đây không phải là điểm của câu hỏi ...
gbn

1
Đừng lo lắng. Cá nhân tôi đồng ý với quan điểm của bạn; Tôi chỉ nhận xét rằng không có mối tương quan trực tiếp giữa kết quả của cấu trúc IF / WHERE EXISTS và THIẾT LẬP NOCOUNT. Tôi nhận được kết quả nhất quán từ các cấu trúc đó bất kể NOCOUNT. Nếu bạn có bất cứ điều gì nói khác, xin vui lòng gửi theo cách của tôi.
Jeremy S

1
@Jeremy Seghi: bạn đã đúng: THIẾT LẬP NOCOUNT ON chỉ chặn gói dữ liệu bổ sung trở lại máy khách. NẾU, @@ ROWCOUNT, v.v ... đều không bị ảnh hưởng. Ồ, và nó phá vỡ SQLDataAd chương ... :-)
gbn

1
@Kieren Johnstone: trong nhận thức muộn, đó là một câu hỏi kém. Tôi sẽ bỏ phiếu để đóng nếu đây không phải là câu hỏi của tôi ...
gbn

Câu trả lời:


245

Ok bây giờ tôi đã thực hiện nghiên cứu của mình, đây là thỏa thuận:

Trong giao thức TDS, SET NOCOUNT ONchỉ lưu 9 byte cho mỗi truy vấn trong khi văn bản "SET NOCOUNT ON" là một con số khổng lồ 14 byte. Tôi đã từng nghĩ rằng 123 row(s) affectedđã được trả về từ máy chủ ở dạng văn bản đơn giản trong một gói mạng riêng nhưng thực tế không phải vậy. Trên thực tế, đó là một cấu trúc nhỏ được gọi là DONE_IN_PROCnhúng trong phản hồi. Đây không phải là một gói mạng riêng biệt nên không có vòng tròn nào bị lãng phí.

Tôi nghĩ rằng bạn có thể dính vào hành vi đếm mặc định hầu như luôn luôn mà không phải lo lắng về hiệu suất. Tuy nhiên, có một số trường hợp, trong đó việc tính toán số lượng hàng trước sẽ ảnh hưởng đến hiệu suất, chẳng hạn như con trỏ chỉ chuyển tiếp. Trong trường hợp đó, NOCOUNT có thể là một điều cần thiết. Ngoài ra, hoàn toàn không cần phải tuân theo phương châm "sử dụng NOCOUNT bất cứ khi nào có thể".

Dưới đây là một phân tích rất chi tiết về tầm quan trọng của SET NOCOUNTcài đặt: http://daleburnett.com/2014/01/everything-ever-wocate-ledge-set-nocount/


Thật. Tôi đã sử dụng SET NOCOUNT ON mãi mãi, nhưng marc_s đã chỉ ra giới hạn của SQLDataAd CHƯƠNG trong câu hỏi khác.
gbn

Cảm ơn. Các byte hoặc kích thước không phải là vấn đề với tôi, nhưng khách hàng phải xử lý nó. Đó là sự phụ thuộc SQLDataAd CHƯƠNG vẫn làm tôi kinh ngạc ...
gbn

2
Cảm ơn câu trả lời của bạn. Tôi sẽ chấp nhận điều này vì các cuộc điều tra của bạn, điều này đã kích hoạt thêm thông tin và công việc từ tôi. Tôi không đồng ý trên đầu mặc dù: nó có thể quan trọng như các câu trả lời khác cho thấy. Chúc mừng, gbn
gbn

13
Đây không phải là số byte bị trì hoãn chuyến đi khứ hồi qua dây mà là kẻ giết người hiệu suất
cuộc đua

1
Trong luồng thông báo TDS và ví dụ là khi người ta chỉ chèn các giá trị vào bảng. DONINPROCThông báo (RPC) hoặc DONE(BATCH) được truyền phát được rowcountđặt thành các hàng bị ảnh hưởng, trong khi done_countcờ là true, bất kể NO_COUNTlà có ON. Phụ thuộc vào việc triển khai lib của máy khách trong các trường hợp khi truy vấn giữ các câu lệnh CHỌN hoặc các cuộc gọi RPC không chọn, nó có thể yêu cầu tắt tính năng ... KHI bị vô hiệu hóa, các hàng vẫn được tính cho câu lệnh chọn, nhưng cờ DONE_COUNTđược đặt thành false. Luôn đọc những gì khách hàng của bạn gợi ý vì nó sẽ diễn giải luồng (tin nhắn) thay vì bạn
Milan Jaric

86

Tôi đã mất rất nhiều công sức để tìm ra số liệu điểm chuẩn thực sự xung quanh NOCOUNT, vì vậy tôi đoán rằng tôi sẽ chia sẻ một bản tóm tắt nhanh chóng.

  • Nếu quy trình được lưu trữ của bạn sử dụng một con trỏ để thực hiện nhiều thao tác rất nhanh mà không có kết quả trả về, thì việc NOCOUNT OFF có thể mất khoảng 10 lần miễn là BẬT nó. 1 Đây là trường hợp xấu nhất.
  • Nếu quy trình được lưu trữ của bạn chỉ thực hiện một thao tác nhanh duy nhất mà không có kết quả trả về, đặt NOCOUNT ON có thể mang lại hiệu suất tăng khoảng 3%. 2 Điều này sẽ phù hợp với quy trình chèn hoặc cập nhật thông thường. (Xem các bình luận về câu trả lời này để biết một số thảo luận về lý do tại sao điều này có thể không luôn luôn nhanh hơn.)
  • Nếu quy trình được lưu trữ của bạn trả về kết quả (nghĩa là bạn CHỌN một cái gì đó), sự khác biệt hiệu suất sẽ giảm tỷ lệ thuận với kích thước của tập kết quả.

5
+1 cho tác động lên con trỏ, điều này phù hợp với các quan sát của tôi
zvolkov

Điểm 2 không chính xác! Tôi có nghĩa là blog mà nó đang đề cập đến. Chưa bao giờ! DONE và DONEPROC và DONEINPROC được gửi với cùng kích thước bất kể NO_COUNT được đặt thành BẬT hay TẮT. RowCount vẫn ở đó vì ULONGLONG (64 byte) và cờ DONE_COUNT vẫn ở đó nhưng giá trị bit là 0. Máy chủ SQL sẽ đếm số lượng hàng dù sao, ngay cả khi bạn không muốn đọc giá trị từ mã thông báo DONE. Nếu bạn đọc @@ ROWCOUNT thì bạn đã thêm nhiều byte vào luồng mã thông báo dưới dạng mã thông báo trả về hoặc dưới dạng mã thông báo hàng hóa + hàng hóa khác!
Milan Jaric

@MilanJaric: Cảm ơn bạn đã gọi nó ra. Bạn đã giúp tôi nhận ra rằng tôi đã liên kết bài viết sai. Liên kết được cập nhật ngay bây giờ và bài viết đưa ra một lập luận hấp dẫn để cho thấy rằng có thể có một sự cải thiện hiệu suất nhẹ với TẬP NOCOUNT ON. Bạn có nghĩ rằng có vấn đề với các phương pháp điểm chuẩn được sử dụng?
StriplingWar Warrior

:) vẫn không chính xác về TẮT / BẬT NOCOUNT, Lỗi là SP thứ hai không có SET NOCOUNT OFF;và đó là lý do tại sao họ nghĩ rằng họ không nhận được thêm byte trong phản hồi. Điểm chuẩn chính xác sẽ được sử dụng SET NOCOUNT ONtrong SET NOCOUNT OFFthủ tục lưu trữ bên trái và bên phải. Bằng cách này, bạn sẽ nhận được gói TDS với DONEINPROC (SET NOCOUNT ...), mười lần nữa DONEINPROC (INSERT statement), và sau đó RETURNVALUE(@@ROWCOUNT), sau đó RETURNSTATUS 0cho sp và cuối cùng DONPROC. Có lỗi vì sp thứ hai không có TẮT NOCOUNT trong cơ thể!
Milan Jaric

Để định nghĩa lại những gì họ tìm thấy nhưng họ không nhận ra rằng nếu bạn có yêu cầu con trỏ tìm nạp 1K, trước tiên hãy thực hiện một yêu cầu đặt NOCOUNT thành BẬT hoặc TẮT để kết nối và sau đó sử dụng cùng một kết nối để gọi con trỏ tìm nạp 1K lần để tiết kiệm băng thông. Trạng thái kết nối thực tế cho NOCOUNT ON hoặc OFF sẽ không ảnh hưởng đến băng thông, nó có thể chỉ gây nhầm lẫn cho lib của khách hàng, ví dụ như ADO.net hoặc ODBC. Vì vậy, "không sử dụng SET NOCOUNT <WHATEVER> nếu bạn quan tâm đến băng thông" :)
Milan Jaric

77
  • Khi SET NOCOUNT được BẬT, số đếm (cho biết số lượng hàng bị ảnh hưởng bởi câu lệnh Transact-SQL) sẽ không được trả về. Khi SET NOCOUNT TẮT, số lượng được trả về. Nó được sử dụng với bất kỳ câu lệnh CHỌN, CHERTN, CẬP NHẬT, XÓA.

  • Cài đặt của SET NOCOUNT được đặt ở thời gian thực thi hoặc chạy và không phải lúc phân tích cú pháp.

  • SET NOCOUNT ON cải thiện hiệu suất thủ tục được lưu trữ (SP).

  • Cú pháp: THIẾT LẬP NOCOUNT {ON | TẮT }

Ví dụ về THIẾT LẬP NOCOUNT:

nhập mô tả hình ảnh ở đây

Ví dụ về TẮT NOCOUNT:

nhập mô tả hình ảnh ở đây


7
Dễ dàng và nhanh chóng để hiểu với ảnh chụp màn hình. Bạn đã làm rất tốt. :)
shaijut

35

Tôi đoán ở một mức độ nào đó đó là vấn đề DBA so với nhà phát triển.

Là một nhà phát triển, tôi nói rằng đừng sử dụng nó trừ khi bạn hoàn toàn tích cực phải làm - bởi vì sử dụng nó có thể phá vỡ mã ADO.NET của bạn (như tài liệu của Microsoft).

Và tôi đoán là một DBA, bạn sẽ có nhiều mặt hơn - sử dụng nó bất cứ khi nào có thể trừ khi bạn thực sự phải ngăn chặn việc sử dụng nó.

Ngoài ra, nếu các nhà phát triển của bạn từng sử dụng "RecordsAffected" được trả về bởi ExecuteNonQuerylệnh gọi phương thức của ADO.NET , bạn sẽ gặp rắc rối nếu mọi người sử dụng SET NOCOUNT ONvì trong trường hợp này, ExecuteNonQuery sẽ luôn trả về 0.

Cũng xem bài viết trên blog của Peter Bromberg và kiểm tra vị trí của anh ấy.

Vì vậy, nó thực sự nắm bắt được ai sẽ thiết lập các tiêu chuẩn :-)

Marc


Anh ấy vào khoảng CRUD đơn giản mặc dù: lưới dữ liệu ông có đề cập có thể sử dụng xml để gửi nhiều hàng để tránh các chuyến đi vòng vv
gbn

Tôi đoán rằng nếu bạn không bao giờ sử dụng SqlDataAd chương và bạn không bao giờ kiểm tra và dựa vào số "bản ghi bị ảnh hưởng" được trả về bởi ExecuteNonQuery (ví dụ: nếu bạn sử dụng một cái gì đó như Linq-to-SQL hoặc NHibernate), thì có lẽ bạn không gặp vấn đề gì sử dụng SET NOCOUNT ON trong tất cả các procs được lưu trữ.
marc_s

12

Nếu bạn đang nói rằng bạn cũng có thể có nhiều khách hàng khác nhau, thì có vấn đề với ADO cổ điển nếu SET NOCOUNT không được đặt thành BẬT.

Một điều tôi thường gặp: nếu một thủ tục được lưu trữ thực thi một số câu lệnh (và do đó, một số thông báo "xxx hàng bị ảnh hưởng" được trả về), ADO dường như không xử lý điều này và ném lỗi "Không thể thay đổi thuộc tính ActiveConnection của đối tượng Recordset trong đó có một đối tượng Command là nguồn của nó. "

Vì vậy, tôi thường ủng hộ việc đặt nó BẬT trừ khi không có lý do thực sự tốt. bạn có thể đã tìm thấy lý do thực sự tốt mà tôi cần phải đọc và đọc thêm.


9

Có nguy cơ làm cho mọi thứ trở nên phức tạp hơn, tôi khuyến khích một quy tắc hơi khác với tất cả những gì tôi thấy ở trên:

  • Luôn luôn đặt NOCOUNT ONở đầu của một Proc, trước khi bạn thực hiện bất kỳ công việc nào trong Proc, nhưng cũng luôn luôn SET NOCOUNT OFFmột lần nữa, trước khi trả lại bất kỳ bản ghi nào từ các Proc được lưu trữ.

Vì vậy, "nói chung hãy tiếp tục, trừ khi bạn thực sự trả lại kết quả". Tôi không biết bất kỳ cách nào mà điều này có thể phá vỡ bất kỳ mã khách hàng nào, điều đó có nghĩa là mã khách hàng không bao giờ cần biết bất cứ điều gì về nội bộ của Proc và nó không đặc biệt khó chịu.


Cảm ơn. Tất nhiên, bạn có thể lấy hàng từ Bộ dữ liệu hoặc bộ chứa tiêu thụ, nhưng có thể hữu ích. Chúng tôi không thể kích hoạt các CHỌN vì vậy điều này sẽ an toàn: hầu hết các lỗi máy khách là do thông báo giả về thay đổi dữ liệu.
gbn

Vấn đề với quy tắc này chỉ là khó kiểm tra hơn "Có phải THIẾT BỊ NOCOUNT ở đầu của Proc không?"; Tôi tự hỏi liệu các công cụ Phân tích SQL như Sql Enlight có thể kiểm tra loại đó không ... Thêm nó vào danh sách việc cần làm dài hạn cho dự án định dạng SQL của tôi :)
Tao

5

Liên quan đến việc kích hoạt NHibernate, tôi đã có trải nghiệm đó trực tiếp. Về cơ bản, khi NH thực hiện CẬP NHẬT, nó dự kiến ​​sẽ có một số hàng nhất định bị ảnh hưởng. Bằng cách thêm SET NOCOUNT ON vào các kích hoạt, bạn sẽ nhận được số lượng hàng trở lại với những gì NH mong đợi do đó khắc phục vấn đề. Vì vậy, vâng, tôi chắc chắn sẽ khuyên bạn nên tắt nó để kích hoạt nếu bạn sử dụng NH.

Về việc sử dụng trong SP, đó là vấn đề sở thích cá nhân. Tôi đã luôn tắt hàng, nhưng sau đó, một lần nữa, không có tranh luận mạnh mẽ thực sự.

Ở một lưu ý khác, bạn thực sự nên xem xét chuyển khỏi kiến ​​trúc dựa trên SP, sau đó bạn thậm chí sẽ không có câu hỏi này.


1
Tôi không đồng ý với việc di chuyển khỏi các procs được lưu trữ. Điều này có nghĩa là chúng ta phải có cùng một SQL trong 2 cơ sở mã khách hàng khác nhau và tin tưởng các bộ mã hóa máy khách của chúng ta. Chúng tôi là nhà phát triển DBA. Và bạn không có nghĩa là "SET NOCOUNT ON "?
gbn

@CodeBlend: chỉ cần Google nó cho nhiều hơn bạn cần. Tuy nhiên ... stackoverflow.com/a/4040466/27535
gbn

3

Tôi muốn tự xác minh rằng 'THIẾT LẬP NOCOUNT' không lưu gói mạng cũng không làm tròn số

Tôi đã sử dụng thử nghiệm SQLServer 2017 trên một máy chủ khác (Tôi đã sử dụng VM) create table ttable1 (n int); insert into ttable1 values (1),(2),(3),(4),(5),(6),(7) go create procedure procNoCount as begin set nocount on update ttable1 set n=10-n end create procedure procNormal as begin update ttable1 set n=10-n end Sau đó, tôi đã theo dõi các gói trên cổng 1433 bằng công cụ 'Wireshark': nút 'bộ lọc chụp' -> 'cổng 1433'

exec procNoCount

đây là gói phản hồi: 0000 00 50 56 c0 00 08 00 0c 29 31 3f 75 08 00 45 00 0010 00 42 d0 ce 40 00 40 06 84 0d c0 a8 32 88 c0 a8 0020 32 01 05 99 fe a5 91 49 e5 9c be fb 85 01 50 18 0030 02 b4 e6 0e 00 00 04 01 00 1a 00 35 01 00 79 00 0040 00 00 00 fe 00 00 e0 00 00 00 00 00 00 00 00 00

exec procNormal

đây là gói phản hồi: 0000 00 50 56 c0 00 08 00 0c 29 31 3f 75 08 00 45 00 0010 00 4f d0 ea 40 00 40 06 83 e4 c0 a8 32 88 c0 a8 0020 32 01 05 99 fe a5 91 49 e8 b1 be fb 8a 35 50 18 0030 03 02 e6 1b 00 00 04 01 00 27 00 35 01 00 ff 11 0040 00 c5 00 07 00 00 00 00 00 00 00 79 00 00 00 00 0050 fe 00 00 e0 00 00 00 00 00 00 00 00 00

Trên dòng 40 tôi có thể thấy '07' là số 'hàng bị ảnh hưởng'. Nó được bao gồm trong gói phản hồi. Không có gói phụ.

Tuy nhiên, nó có thêm 13 byte có thể được lưu, nhưng có lẽ không đáng giá hơn việc giảm tên cột (ví dụ: 'ManageDepidor' thành 'MD')

Vì vậy, tôi thấy không có lý do để sử dụng nó cho hiệu suất

NHƯNG Như những người khác đã đề cập, nó có thể phá vỡ ADO.NET và tôi cũng vấp phải một vấn đề khi sử dụng python: MSSQL2008 - Pyodbc - SQL trước đó không phải là một truy vấn

Vì vậy, có lẽ một thói quen tốt vẫn ...


1
SET NOCOUNT ON;

Dòng mã này được sử dụng trong SQL để không trả về các hàng số bị ảnh hưởng trong quá trình thực hiện truy vấn. Nếu chúng tôi không yêu cầu số lượng hàng bị ảnh hưởng, chúng tôi có thể sử dụng điều này vì điều này sẽ giúp tiết kiệm việc sử dụng bộ nhớ và tăng thời gian thực hiện truy vấn.


2
Lưu ý rằng @@ ROWCOUNT vẫn được đặt. THIẾT LẬP NOCOUNT ON ngăn chặn mọi phản hồi bổ sung mà SQL Server gửi đến máy khách. Xem câu trả lời được chấp nhận ở trên xin vui lòng
gbn

1

THIẾT LẬP NOCOUNT; Mã ở trên sẽ dừng thông báo được tạo bởi công cụ máy chủ sql đến cửa sổ kết quả phía trước sau khi thực hiện lệnh DML / DDL.

Tại sao chúng ta làm điều đó? Vì công cụ máy chủ SQL cần một số tài nguyên để nhận trạng thái và tạo thông báo, nó được coi là quá tải đối với công cụ máy chủ Sql. Vì vậy, chúng tôi đặt thông báo không đếm được.


1

Một nơi SET NOCOUNT ONthực sự có thể giúp là nơi bạn đang thực hiện các truy vấn trong một vòng lặp hoặc một con trỏ. Điều này có thể thêm tối đa lưu lượng mạng.

CREATE PROCEDURE NoCountOn
AS
set nocount on
    DECLARE @num INT = 10000
    while @num > 0
    begin
       update MyTable SET SomeColumn=SomeColumn
       set @num = @num - 1
    end
GO


CREATE PROCEDURE NoCountOff
AS
set nocount off
    DECLARE @num INT = 10000
    while @num > 0
    begin
       update MyTable SET SomeColumn=SomeColumn
       set @num = @num - 1
    end
GO

Bật số liệu thống kê của khách hàng trong SSMS, một lần chạy EXEC NoCountOnEXEC NoCountOffcho thấy rằng có thêm lưu lượng truy cập 390KB trên NoCount Offer:

thống kê khách hàng

Có lẽ không lý tưởng để thực hiện các truy vấn trong một vòng lặp hoặc con trỏ, nhưng chúng ta cũng không sống trong thế giới lý tưởng :)


0

Tôi biết đó là câu hỏi khá cũ. nhưng chỉ để cập nhật.

Cách tốt nhất để sử dụng "THIẾT LẬP NOCOUNT ON" là đưa nó lên như một câu lệnh đầu tiên trong SP của bạn và đặt lại TẮT ngay trước câu lệnh CHỌN cuối cùng.


-1

Tôi không biết cách kiểm tra SET NOCOUNT ON giữa máy khách và SQL, vì vậy tôi đã thử nghiệm một hành vi tương tự cho lệnh SET khác "SET TRANSACTION ISOLATION LEVEL READ UNCIMMITTED"

Tôi đã gửi một lệnh từ kết nối của mình thay đổi hành vi mặc định của SQL (READ CAMITED) và nó đã được thay đổi cho các lệnh tiếp theo. Khi tôi thay đổi mức ISOLATION trong một thủ tục được lưu trữ, nó không thay đổi hành vi kết nối cho lệnh tiếp theo.

Kết luận hiện tại,

  1. Thay đổi cài đặt bên trong quy trình được lưu trữ sẽ không thay đổi cài đặt mặc định của kết nối.
  2. Thay đổi cài đặt bằng cách gửi lệnh bằng ADOCOnnection sẽ thay đổi hành vi mặc định.

Tôi nghĩ rằng điều này có liên quan đến lệnh SET khác, chẳng hạn như "SET NOCOUNT ON"


Điểm 1 của bạn ở trên có ngụ ý rằng bạn không thực sự cần phải TẠO NOCOUNT ở cuối vì nó không ảnh hưởng đến môi trường toàn cầu?
funkymushroom

Tôi không chắc đó có phải ý của anh ấy với điểm 1 hay không, nhưng trong các thử nghiệm của tôi, vâng, rõ ràng môi trường toàn cầu không bị ảnh hưởng bởi SET NOCOUNT ON trong một thủ tục được lưu trữ.
Doug

Đây là một lựa chọn so sánh kém, bởi vì Mức cô lập có liên quan rõ ràng với một giao dịch cụ thể, vì vậy không có lý do cụ thể nào để mong đợi nó phù hợp với một cài đặt nhưNOCOUNT
IMSoP

-1

if (set no Count == off)

{sau đó nó sẽ giữ dữ liệu có bao nhiêu bản ghi bị ảnh hưởng để giảm hiệu suất} khác {nó sẽ không theo dõi bản ghi các thay đổi do đó cải thiện perfomace}}


-1

Đôi khi ngay cả những điều đơn giản nhất cũng có thể tạo ra sự khác biệt. Một trong những mục đơn giản nên là một phần của mọi thủ tục được lưu trữ là SET NOCOUNT ON. Một dòng mã này, được đặt ở đầu của một thủ tục được lưu trữ sẽ tắt các thông báo mà SQL Server gửi lại cho máy khách sau khi mỗi câu lệnh T-SQL được thực thi. Này được thực hiện cho tất cả SELECT, INSERT, UPDATE, và DELETEbáo cáo. Có thông tin này rất hữu ích khi bạn chạy câu lệnh T-SQL trong cửa sổ truy vấn, nhưng khi các thủ tục được lưu trữ được chạy, không cần thông tin này được gửi lại cho máy khách.

Bằng cách loại bỏ chi phí phụ này khỏi mạng, nó có thể cải thiện hiệu năng tổng thể cho cơ sở dữ liệu và ứng dụng của bạn.

Nếu bạn vẫn cần lấy số lượng hàng bị ảnh hưởng bởi câu lệnh T-SQL đang thực thi, bạn vẫn có thể sử dụng @@ROWCOUNTtùy chọn. Bằng cách ban hành một SET NOCOUNT ONhàm này ( @@ROWCOUNT) vẫn hoạt động và vẫn có thể được sử dụng trong các thủ tục được lưu trữ của bạn để xác định có bao nhiêu hàng bị ảnh hưởng bởi câu lệnh.

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.