2010-08-17 20 views
10

Tôi đã thấy điều này hiển thị một vài vị trí trong mã, không bao giờ có giải thích, chỉ là một nhận xét khó hiểu ở trên nó (Tuyên bố và thực hiện bao gồm ý tưởng ngữ cảnh. Đó là một quy trình chuẩn để chạy một SqlCommand):SqlCommand.Cancel() làm tăng hiệu năng?

//SqlCommand cmd = new SqlCommand(); 
//cmd.ExecuteReader(); 
//Read off the results 

//Cancel the command. This improves query time. 
cmd.Cancel(); 

Về cơ bản, sau khi hoàn thành một truy vấn, nó quay trở lại và hủy bỏ nó, tuyên bố một số tăng hiệu suất. Tôi cho rằng bạn có thể nhận được một số bộ nhớ trở lại khi nó đi và giải phóng các XmlReader, nhưng thường là nó về để đi ra khỏi phạm vi anyways.

Tôi chưa bao giờ làm phiền với nó trước đây, nhưng cuối cùng nó cũng xuất hiện trong một số mã tôi đang xem xét. Có hủy bỏ một SqlCommand sau khi chạy nó trong mã thực sự bằng cách nào đó tốc độ nó lên, hoặc là điều này chỉ là một số mê tín dị đoan lập trình kỳ lạ?

+0

Bạn đã lược tả mã chưa? Nó sẽ là thú vị để xem có bao nhiêu ảnh hưởng đến nó thực sự có. – jloubert

+0

Có một trường hợp quan trọng trong đó việc gọi Hủy tạo ra sự khác biệt lớn - xem câu trả lời của tôi bên dưới –

Trả lời

13

Theo MSDN, điều này là chính xác.

Các Đóng phương pháp điền vào các giá trị cho các thông số đầu ra, trở lại giá trị và RecordsAffected, tăng thời gian mà nó cần để đóng một SqlDataReader đã được sử dụng để xử lý một truy vấn lớn hoặc phức tạp. Khi giá trị trả về và số lượng hồ sơ bị ảnh hưởng bởi một truy vấn không đáng kể, thời gian mà nó cần để đóng SqlDataReader có thể giảm bằng cách gọi Hủy bỏ phương pháp của đối tượng SqlCommand liên quan trước khi gọi Close phương pháp.

Lạ!

+0

Huh. Không nghĩ đến việc tìm kiếm tài liệu SqlDataReader. Nắm bắt tốt! –

+1

Tìm kiếm @ mã cơ bản, rõ ràng là nó thực hiện một số lượng công việc hợp lý trên Close, tuy nhiên, tôi sẽ không tưởng tượng trong một khoảnh khắc rằng đây là tất cả những gì đáng kể vào cuối ngày. –

+0

Đã học được điều gì đó ;-) Mặc dù tôi đồng ý rằng bạn phải bị tắc nghẽn nghiêm trọng trên DB IO để nhận thấy sự thay đổi. – gjvdkamp

0

Nhóm Kỹ thuật của chúng tôi tại Cinchcast đã thực hiện một số điểm chuẩn và chúng tôi nhận thấy rằng việc thêm cmd.Cancel() thực sự làm chậm tốc độ.

Chúng tôi có cuộc gọi DALC nhận danh sách tập cho một máy chủ lưu trữ. Chúng tôi đã chạy 1000 lần và nhận được thời gian phản hồi trung bình để trả về 10 tập.

Vì vậy, với trở về 10 cho thấy Average Với Cancel: 0.069s Trung bình Không Cancel: 0.026s

Khá đáng kể chậm hơn khi chạy với trở về 10 tập phim.

Vì vậy, tôi đã thử lại với 100 tập phim để xem liệu tập hợp kết quả lớn hơn có tạo ra sự khác biệt hay không.

Vì vậy, với trở 100 chương trình trên mỗi cuộc gọi Average Với Cancel: 0.132s Trung bình Không Cancel: 0.122s

Vì vậy, lần này sự khác biệt về thời gian là ít hơn nhiều. Nó vẫn còn nhanh hơn mặc dù không sử dụng Hủy cho các trường hợp sử dụng thông thường của chúng tôi.

7

Calling Cancel đưa ra một khả năng cải thiện hiệu suất MASSIVE nếu cuộc gọi của bạn để ExecuteReader trả về một số lượng lớn các hàng, và bạn không đọc tất cả các hàng.

Để minh họa, giả sử truy vấn trả về hàng triệu hàng và bạn đóng trình đọc sau khi chỉ đọc 1000 hàng đầu tiên. Nếu bạn thất bại trong việc gọi Cancel trước khi chốt đọc, phương pháp Close sẽ khối trong khi nó trong nội bộ liệt kê thông qua 999.000 hàng còn lại

Hãy thử nó và xem!

+0

Nó không thể được quá understated đủ bao nhiêu "Đừng đọc tất cả các hàng" là chức năng chính của phương pháp này. – JJS

0

Trong ví dụ của bạn, bạn mở trình đọc, đọc tất cả các hàng và hủy lệnh, nhưng bạn không hiển thị nơi trình đọc đang được đóng.

Đảm bảo việc hủy xảy ra trướcDispose/Close. Ví dụ, bạn sẽ không có được một tăng hiệu suất trong ví dụ này (mã thực trong sản xuất, không may):

using (var rdr = cmd.ExecuteReader (CommandBehavior.Default)) 
{ 
    retval = DocumentDir.DBRead (rdr); 
} 

// Optimization. Allows reader to close more quickly.... NOT! 
cmd.Cancel(); // bad! 

Quá xấu nó đã được đóng bởi Tuyên bố dùng!

Đây là cách nó nên đọc để nhận ra những lợi ích tiềm năng:

using (var rdr = cmd.ExecuteReader (CommandBehavior.Default)) 
{ 
    retval = DocumentDir.DBRead (rdr); 

    // Optimization. Allows reader to close more quickly. 
    cmd.Cancel(); 
} 

Từ MSDN SqlCommand.Cancel:

Trong một số, hiếm, trường hợp, nếu bạn gọi ExecuteReader sau đó gọi Close (ẩn hoặc rõ ràng) trước khi gọi Hủy, và sau đó gọi Hủy, lệnh hủy sẽ không được gửi đến SQL Server và tập kết quả có thể tiếp tục phát sau khi bạn gọi Đóng. Để tránh điều này, hãy chắc chắn rằng bạn gọi Hủy trước khi đóng trình đọc hoặc kết nối.

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