TSQL: Tìm các Truy vấn gây ra quá nhiều Biên dịch SQL và Tái cấu trúc SQL riêng biệt


8

Tôi muốn tìm hiểu điều gì gây ra các Biên dịch SQL cao (không phải là biên dịch lại) mà tôi đang thấy trong các bộ đếm màn hình hiệu suất.

Đây là ý kiến ​​của tôi về nó: Nếu tôi thấy rất nhiều phần tổng hợp SQl, thì điều đó có nghĩa là các truy vấn trên hệ thống của chúng tôi không được lưu vào bộ nhớ cache vì những lý do sau:

  • Nhiều truy vấn adhoc
  • Chạy các truy vấn mà SQl không lưu cache, ví dụ:

    CẬP NHẬT bảng1 SET col1 = 'Chuỗi dài hơn 8000 ký tự .....' WHERE key_column = some int

  • Các kế hoạch đã hết thời gian và bị xóa khỏi bộ đệm vì: Bộ nhớ cache sắp hết dung lượng hoặc các gói không được sử dụng đủ lâu.

Điều duy nhất tiến gần đến việc chèn các bộ đệm trong bộ đệm là Trình thủ tục được lưu trữ-> SP: CacheInserts nhưng nó chỉ xem sau bộ đệm thủ tục được lưu trữ.

Vì vậy, tôi đã thử các cách sau để có được các truy vấn adhoc:

SELECT [cp].[refcounts] -- when Refcounts becomes 0, plan is excluded from cache.
    , [cp].[usecounts] 
    , [cp].[objtype] 
    , st.[dbid] 
    , st.[objectid] 
    , st.[text] 
    , [qp].[query_plan] 
FROM sys.dm_exec_cached_plans cp     
CROSS APPLY sys.dm_exec_sql_text ( cp.plan_handle ) st     
CROSS APPLY sys.dm_exec_query_plan ( cp.plan_handle ) qp ;

Tôi nghĩ các truy vấn gây ra các trình biên dịch nên là các truy vấn có objtype = Adhoc nhưng điều này cũng có thể liên quan đến các biên dịch lại. Bây giờ tôi phải chạy profiler, nắm bắt các truy vấn gây ra các phần tổng hợp lại và sau đó loại bỏ nó khỏi danh sách trên.

Tôi đang đi đúng hướng?

Có một truy vấn duy nhất nào tôi có thể sử dụng để đạt được các phần tổng hợp SQL mà không cần quá nhiều công việc không?

Tài nguyên giúp tôi đạt được những kiến ​​thức trên:

http://social.msdn.microsoft.com/Forums/en/sqldatabaseengine/thread/954b4fba-3774-42e3-86e7-e5172abe0c83 http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=143946 http: //technet.microsoft.com/en-nz/l Library / cc966425 (en-us) .aspx
http://www.sqlservercentral.com/Forums/Topic914951-360-1.aspx

Bất kỳ trợ giúp được thực sự đánh giá cao.

Câu trả lời:


7

Tôi không nghĩ rằng bạn có thể tìm thấy điều này một cách dễ dàng nhưng dù sao cũng có thể vượt qua điều này. Profiler cung cấp nhiều loại lớp sự kiện có thể được sử dụng để phân tích hiệu suất của truy vấn. Bắt đầu một phiên Profiler mới và kiểm tra các sự kiện sau:

Performance: Performance statistics
Stored Procedures: RPC:Completed
TSQL: SQL:BatchCompleted
TSQL: SQL: BatchStarting

Kiểm tra để hiển thị tất cả các cột và chọn từng cột trong Hiệu suất: Chỉ sự kiện thống kê hiệu suất. Phần còn lại của các sự kiện có thể được để lại với cài đặt mặc định.

Tiếp theo, chọn Bộ lọc cột và bộ lọc theo DatabaseName và / hoặc LoginName / ApplicationName / HostName, v.v., nếu bạn biết chúng. Mục đích là để giới hạn số lượng hàng được phân phối trong Profiler và chỉ tập trung vào nhu cầu của bạn.

Tiếp theo, nhấn Run và để nó chạy một lúc (2-3 phút miễn là bạn cần). Phân tích các kết quả được phân tích chủ yếu nhìn vào: Sự kiện thống kê hiệu suất.

Nếu Thống kê hiệu suất sẽ xảy ra thường xuyên, điều đó có nghĩa là lần đầu tiên kế hoạch truy vấn được lưu vào bộ nhớ cache, được biên dịch, biên dịch lại hoặc bị trục xuất khỏi PlanCache. Theo hiểu biết của tôi nếu một truy vấn không có gói truy vấn của nó trong Plan Cache - bạn sẽ thấy 2 hàng sự kiện PerformanceStatistic và theo sau là SQL: BatchStarting , sau đó là SQL: BatchCompleted . Điều đó có nghĩa là Kế hoạch truy vấn được biên dịch, lưu vào bộ đệm và sau đó truy vấn bắt đầu và hoàn thành.

Nhìn vào các cột sau trong sự kiện Thống kê hiệu suất:

SPID - ID of the session on which the event occurred. You can use it to identify the       
       row on SQL:BatchCompleted event which will display the SQL Query text and other  
       usefull information (Read/Writes, StartTime/EndTime)
Duration - Total time, in microseconds, spent during compilation.
EventSubClass - 0 = New batch SQL text that is not currently present in the cache.
                1 = Queries within a stored procedure have been compiled.
                2 = Queries within an ad hoc SQL statement have been compiled.
                3 = A cached query has been destroyed and the historical performance         
                    data associated with the plan is about to be destroyed.
                4 = A cached stored procedure has been removed from the cache and the  
                    historical performance data associated with it is about to be 
                    destroyed.

                5 = A cached trigger has been removed from the cache and the historical  
                    performance data associated with it is about to be destroyed.

Xem xét số EventSubClass, bạn có thể tìm hiểu điều gì đã xảy ra với Gói truy vấn và thực hiện các biện pháp cụ thể. Ngoài ra, bạn có thể thêm các cột khác vào Thủ tục lưu trữ và Lớp sự kiện TSQL nếu bạn được xen kẽ trong HostName, WindowsUser hoặc thông tin khác từ theo dõi Profiler. Ngoài ra, theo dõi có thể được lưu trữ trong một bảng SQL làm cho việc phân tích dễ dàng hơn và tùy biến hơn nhiều. Đây là một liên kết mô tả thêm Lớp Sự kiện Thống kê Hiệu suất.


4

Chà, trước tiên hãy xem có áp lực lên bộ đệm không.

select bpool_visible from sys.dm_os_sys_info
go

Nhân số đó với 8 để có bộ nhớ trong K. 75% số này từ 0-4G + 10% số này từ 4G-64G + 5% của bất kỳ số nào nữa là giới hạn áp suất bộ nhớ cache của gói . Nếu bạn đạt 75% giới hạn này, SQL Server sẽ bắt đầu xóa các gói từ bộ đệm. Việc thanh lọc này xảy ra khi một gói truy vấn mới được thêm vào bộ đệm, do đó luồng sẽ tạm dừng để thực hiện công việc này. Điều thứ hai có thể khiến các kế hoạch bị thanh trừng là nếu số lượng kế hoạch vượt quá 4 lần số lượng hàm băm (một bảng băm ánh xạ plan_handle vào một kế hoạch). Có 10.000 trên hệ thống 32 bit và 40.000 trên hệ thống 64 bit.

select type, sum(pages_allocated_count) as pages_used from sys.dm_os_memory_objects 
where type in ('MEMOBJ_CACHESTOREOBJCP', 'MEMOBJ_CACHESTORESQLCP', 'MEMOBJ_CACHESTOREXPROC')
group by type
go

Quyết định về những gì cần thanh lọc không được đưa ra khi sử dụng, nhưng về chi phí của kế hoạch, các kế hoạch rẻ nhất sẽ bị thanh trừng trước tiên (chi phí để sản xuất, không thực hiện). Bạn có thể thấy điều này nếu bạn thêm các cột original_costcurrent_costtruy vấn của bạn trên sys.dm_exec_cached_plans. Một kế hoạch đặc biệt bắt đầu từ 0 và được tăng thêm 1 mỗi khi nó được sử dụng. Khi áp suất bộ đệm xảy ra, SQL Server sẽ trừ một nửa từ mỗi chi phí, sau đó loại bỏ những người đã đạt đến 0.

Nếu bạn có nhiều SQL đặc biệt, hãy thử:

exec sp_reconfigure 'optimize for ad hoc workloads', 1
go
reconfigure
go

Trong chế độ này, SQL Server chỉ lưu trữ một "sơ khai", kích thước khoảng 300 byte (kế hoạch truy vấn thông thường tối thiểu 24k), chứa hàm băm và con trỏ tới văn bản SQL, lần đầu tiên nó nhìn thấy một câu lệnh SQL cụ thể sau đó lưu trữ toàn bộ kế hoạch nếu nó được thực hiện lại. Điều này sẽ không nhất thiết phải tự cắt giảm các phần tổng hợp, nhưng nó sẽ giảm áp lực bộ nhớ lên bộ đệm của kế hoạch.

Lưu ý: Điều này hoạt động trong năm 2008, không thử nó vào năm 2005.

Một mẹo khác là

alter database ... set parameterization forced
go

Điều này sẽ gây ra SQL Server để hằng trị như các thông số, có thể giúp với autoparameterization tính năng mà thường lưu trữ kế hoạch cho câu lệnh SQL tương tự. Ad-hoc SQL nên lưu các gói truy vấn của nó, trừ khi máy chủ của bạn rất thiếu bộ nhớ, nhưng điều này phụ thuộc vào các kết quả khớp văn bản chính xác trừ khi nó có thể được tham số hóa, trong trường hợp đó nó hoạt động giống như một truy vấn đã chuẩn bị.


Cảm ơn! Tôi biết tùy chọn "bắt buộc tham số hóa" này nhưng sợ sử dụng nó. Nhược điểm duy nhất mà tôi có thể thấy khi sử dụng nó là nó sẽ lấp đầy bộ đệm. Tôi có đúng không
Manjot

3

Bạn có nhiều công việc SQL Server thường xuyên chạy trên hộp này không? Lưu ý rằng trong năm 2005, các truy vấn công việc của tác nhân KHÔNG được lưu trong bộ nhớ cache và cũng có thể gây ra các phần tổng hợp bộ đệm & bộ đệm.

Nhìn vào số lượng kế hoạch với số lượng tái sử dụng thấp. Đó là những thủ phạm của bạn.

Một số lưu ý liên quan về kế hoạch bộ nhớ đệm ở bên dưới.

http://www.sqlskills.com/BLOGS/KIMBERLY/post/Plan-cache-adhoc-workloads-and-clear-the-single-use-plan-cache-bloat.aspx

http://www.sqlskills.com/BLOGS/KIMBERLY/post/Clear-the-cache-are-there-other-options.aspx


0

Hiệu ứng này được gọi là "ô nhiễm kế hoạch truy vấn", trong đó nhiều truy vấn SQL tương tự tạo ra các kế hoạch thực hiện riêng biệt nhưng tương đương.

Các truy vấn Ad-Hoc gây ra chi phí bằng cách phân tích cú pháp riêng lẻ, nhưng thường không gây ô nhiễm kế hoạch, vì kế hoạch của chúng không được lưu trữ. Điều này khác với các truy vấn chỉ có một tham số (trong MS SQL Server), các truy vấn này sẽ được xử lý như một truy vấn được tham số hóa.

Có một số trường hợp điển hình cho ô nhiễm kế hoạch truy vấn:

  • Các truy vấn SQL chỉ có một tham số bằng chữ được mã hóa cứng (như 'select id, name from person where id = 1234')
  • đặc biệt là nếu được sử dụng với các lệnh / thủ tục được lưu trữ buộc cơ sở dữ liệu lưu trữ kế hoạch truy vấn, chẳng hạn như 'sp_prepexec' hoặc sp_executesql 'trong MSSQL (Tôi nghĩ rằng' thực thi ngay lập tức 'trong Oracle hoạt động theo cách tương tự)
  • truy vấn được tham số hóa một phần, với sự khác biệt lớn trong các giá trị theo nghĩa đen 'được mã hóa cứng', chẳng hạn như 'select * từ SoccerMatches sm trong đó sm.Date>?' và sm.Date <? và HomeClubId = 5678 và GuestClubId = 1234 '. Chúng sẽ lưu các gói truy vấn do các tham số, nhưng tạo một gói truy vấn mới cho mỗi HomeClub hoặc GuestClub đã thay đổi (đặc biệt vì các giá trị Ngày / Giờ là một dịp tuyệt vời để giới thiệu các tham số trong nhiều API DB, khi các truy vấn không thành công do ngày khác nhau cục bộ định dạng).
  • Một nguồn gây ô nhiễm kế hoạch truy vấn khác có thể là các khung như ADO.NET với trình điều khiển không đủ, kết hợp với các giá trị varchar chuỗi / (n). Một số triển khai / trình điều khiển sẽ đặt kích thước tham số thành độ dài chuỗi thực tế, gây ra một kế hoạch truy vấn riêng cho mỗi độ dài tham số chuỗi khác nhau trong truy vấn. Thực tiễn tốt nhất dường như là việc sử dụng kích thước trường tối đa (ví dụ: varchar (4000)) hoặc trình điều khiển có độ dài chính xác
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.