Khi nào sp_executesql làm mới kế hoạch truy vấn?


13

Bạn sẽ phải tha thứ cho sự ngây thơ của tôi vì tôi không phải là một DBA nhưng tôi hiểu rằng theo thời gian, số liệu thống kê về thay đổi cơ sở dữ liệu và một thủ tục được lưu trữ phải được biên dịch lại để cập nhật kế hoạch truy vấn với các số liệu thống kê mới nhất.

Giả sử tôi có một thủ tục được lưu trữ trong cơ sở dữ liệu của mình được biên dịch lại theo các thống kê mới nhất tại một khoảng thời gian thông thường, ý nghĩa của việc lót trong thủ tục được lưu trữ trong mã và gói nó trong một sp_executesqlcâu lệnh là gì? Tôi có bị mất việc làm mới kế hoạch truy vấn đã từng xảy ra như là một phần của quá trình biên dịch lại thủ tục không?

Nếu có bất cứ điều gì khác (ngoài quyền) mà tôi cần xem xét trước khi tôi thực hiện thay đổi này thì tôi sẽ đánh giá cao những hiểu biết của bạn.

Tôi đọc cái này trên MSDN:

Khả năng của trình tối ưu hóa truy vấn SQL Server phù hợp với chuỗi Transact-SQL mới với kế hoạch thực hiện hiện có bị cản trở bởi các giá trị tham số thay đổi liên tục trong văn bản của chuỗi, đặc biệt là trong các câu lệnh Transact-SQL phức tạp.

Vì vậy, giả sử quy trình được lưu trữ mà tôi đang cố gắng sp_executesqlthực hiện và thực hiện có chứa một số tham số, điều này có nói rằng mặc dù kế hoạch thực hiện của tôi được lưu trong bộ nhớ cache, tôi có gặp khó khăn hơn khi SQL Server tìm và sử dụng lại không?

Câu trả lời:


7

Dòng từ MSDN đang nói về việc sử dụng EXEC(), như thế này:

SET @sql = 'SELECT foo FROM dbo.bar WHERE x = ''' + @x + ''';';
EXEC(@sql);

Trong thử nghiệm của tôi, các phiên bản SQL Server hiện đại vẫn có thể sử dụng lại một kế hoạch như thế này, nhưng có thể có các biến khác (chẳng hạn như phiên bản hoặc ví dụ nếu bạn thêm WHEREcác mệnh đề có điều kiện dựa trên sự hiện diện của các tham số nhất định - trong trường hợp đó sẽ tạo ra một kế hoạch khác nhau).

Nếu bạn sử dụng sp_executesqlthì các giá trị tham số vẫn có thể gây ra sự cố đánh hơi tham số (giống như với SQL thông thường), nhưng điều này không liên quan gì đến việc SQL Server có thể sử dụng lại kế hoạch hay không. Gói này sẽ được sử dụng nhiều lần, giống như bạn hoàn toàn không sử dụng sp_executesql, trừ khi các biến sẽ khiến một truy vấn trực tiếp được biên dịch lại, trong trường hợp này, cái này cũng sẽ được biên dịch lại (về cơ bản, SQL Server không lưu trữ bất cứ thứ gì với gói có nội dung "điều này đã được thực hiện từ sp_executesql, nhưng cái này thì không):

SET @sql = N'SELECT foo FROM dbo.bar WHERE x = @x;';
EXEC sp_executesql @sql, N'@x VARCHAR(32)', @x;

Như một phần thưởng, điều này có tích hợp bảo vệ chống lại SQL động và tránh cho bạn phải lo lắng về việc nhân đôi các trích dẫn đơn do các dấu phân cách chuỗi. Tôi viết blog về một số điều này ở đây .

Nếu bạn đang gặp vấn đề với kế hoạch tái sử dụng và / hoặc tham số sniffing, một số điều bạn nên xem xét là OPTION (RECOMPILE), OPTIMIZE FOR, optimize for ad hoc workloadssimple/forced parameterization. Tôi đã giải quyết một vài câu hỏi tương tự để trả lời cho một webcast gần đây ở đây, nó có thể đáng để đọc lướt qua:

http://sqlperformance.com/performance-palooza

Ý chính là: đừng ngại sử dụng sp_executesqlmà chỉ sử dụng nó khi bạn cần và chỉ tiêu tốn năng lượng để tối ưu hóa nó khi bạn gặp vấn đề về hiệu suất thực tế. Ví dụ trên là một ví dụ tồi tệ vì không có lý do để sử dụng SQL động ở đây - Tôi đã viết câu trả lời này giả sử bạn có trường hợp sử dụng hợp pháp.


2

Các truy vấn được chạy qua sp_executesql tuân theo cùng các quy tắc của kế hoạch thực hiện như các truy vấn thông thường không chạy qua sp_executesql. Nếu văn bản truy vấn thay đổi thì một kế hoạch mới được tạo ra. Nếu văn bản không thay đổi do người sử dụng tham số thì kế hoạch được sử dụng lại. Khi số liệu thống kê được cập nhật thì kế hoạch hết hạn và kế hoạch mới được tạo trong lần truy vấn tiếp theo.


Cảm ơn câu trả lời của bạn, tôi đã thực hiện một chỉnh sửa liên quan đến các tham số vì giờ đây tôi nhận ra rằng mỗi lần tôi gọi sp_ExecuteSql tôi sẽ sử dụng một chuỗi khác nhau làm truy vấn do thực tế là, từ quan điểm của Sql Server, tôi đã thay thế các tham số với các giá trị được mã hóa cứng (chúng sẽ được nhập vào mã trước khi tôi gửi truy vấn của mình đến Sql Server). Bạn có biết một cách xung quanh này? Việc khai báo các biến trong câu lệnh sql nội tuyến của tôi có giúp trình tối ưu hóa truy vấn tìm kế hoạch truy vấn được lưu trong bộ nhớ cache của tôi không?
james lewis
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.