2011-12-05 40 views
5

Câu hỏi này không phải là quá nhiều về việc tìm kiếm giải pháp về việc nhận được giải thích cho hành vi bizarrest bizarrest mà tôi từng thấy từ SQL Server.Hiệu suất quy trình được lưu trữ - đây là WILD?

Tôi đã có một thủ tục lưu trữ với các chữ ký sau:

alter procedure MySP @param1 uniqueidentifier, 
        @param2 uniqueidentifier, 
        @param3 uniqueidentifier 

Cho một tập hợp một số thông số, proc này đã tham gia một thời gian rất dài để chạy từ C# (sử dụng SqlCommand.ExecuteReader()) - khoảng 2 phút. Sử dụng cùng các tham số trong phiên truy vấn trực tiếp, SP chạy trong dưới 2 giây.

Phải mất một thời gian dài, và tôi thậm chí sẽ không cố gắng giải thích cách chúng tôi stumbled khi giải pháp này, nhưng đây là những gì chúng tôi đã làm:

Vào đầu SP, chúng tôi tuyên bố 3 biến địa phương và gán chúng với các giá trị của các thông số, như vậy:

declare @param1_copy uniqueidentifier, 
     @param2_copy uniqueidentifier, 
     @param3_copy uniqueidentifier 

select @param1_copy = @param1, 
     @param2_copy = @param2, 
     @param3_copy = @param3 

Và sau đó, trong phần còn lại của SP chúng tôi thay thế tất cả các tham chiếu đến các thông số đầu vào với các bản sao địa phương.

Thì đấy. SP được thực hiện dưới 2 giây. Và đội bóng ở đây là gobsmacked.

Bây giờ, thưa quý vị, mọi người có thể giải thích hành vi này không?

Trả lời

8

Điều này nghe có vẻ như parameter sniffing.

Từ định nghĩa của Microsoft:

"Parameter đánh hơi" dùng để chỉ một quá trình trong đó môi trường thực thi SQL Server "ngửi" các giá trị tham số hiện tại trong biên soạn hoặc biên dịch lại, và vượt qua nó cùng với truy vấn tối ưu để họ có thể được sử dụng để tạo các kế hoạch thực hiện truy vấn có khả năng nhanh hơn. Từ "hiện tại" đề cập đến các giá trị tham số có trong lời gọi lệnh tạo ra một biên dịch hoặc biên dịch lại.

Hình như bạn đã tìm ra một sửa chữa, khác sẽ được sử dụng EXEC ... VỚI biên dịch lại:

Khi thực hiện một thủ tục lưu trữ với giá trị tham số không điển hình, "EXEC ... WITH RECOMPILE "có thể được sử dụng để đảm bảo rằng kế hoạch truy vấn mới không thay thế gói bộ nhớ đệm hiện có được biên dịch bằng cách sử dụng các giá trị thông số điển hình.

+1

Tuyệt vời. Chúng tôi vấp phải giải pháp sách giáo khoa mà không nhận ra! –

3

Tôi khuyên bạn nên đọc bài viết tuyệt vời của Erland Sommarskog: Slow in the Application, Fast in SSMS? Understanding Performance Mysteries.

Nó có đầy đủ chi tiết về vấn đề này.

Nói chung, khi một kế hoạch truy vấn được lưu trong bộ nhớ cache, một số cài đặt truy vấn được sử dụng trong khóa bộ nhớ cache. Các cài đặt này khác nhau trong cài đặt SSMS mặc định so với cài đặt mặc định trên chuỗi kết nối mặc định, vì vậy các kế hoạch truy vấn khác nhau có thể tồn tại.

+0

Có lẽ tốt nhất sử dụng một từ khác với 'tham số' ở đây để tránh nhầm lẫn với các tham số thủ tục được lưu trữ. –

+0

@MartinSmith - điểm công bằng. Thay đổi thành 'cài đặt' - bạn nghĩ sao? – Oded

+0

Có vẻ tốt với tôi. DMO có thể tìm thấy ở đây là 'sys.dm_exec_plan_attributes' –

0

Tôi đã có một tình huống tương tự khi tôi có tham số kiểu xml và đã dành nhiều thời gian để thực thi.Tôi đã làm cách tiếp cận tương tự và tạo ra một biến địa phương và thông qua các giá trị tham số và nó làm việc siêu nhanh :)

Khi SQL bắt đầu biên dịch SP để tạo kế hoạch thực hiện, nó sẽ tính đến các giá trị được chuyển trong các tham số của nó ảnh hưởng đến kế hoạch thực hiện. Nhưng nếu bạn gán giá trị tham số cho biến cục bộ và sử dụng biến đó trong mã SP của bạn, thì SQL sẽ không đưa các tham số vào tài khoản để ảnh hưởng đến kế hoạch thực thi, do đó bạn nhận được phản hồi nhanh hơn từ truy vấn.

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