2011-08-19 16 views
5

Gần đây chúng tôi đã có một vấn đề hiệu suất và điều này đã được giải quyết bằng cách thực hiện DBCC freeproccache ... Bây giờ, chúng tôi có rất nhiều câu hỏi để trả lời;DBCC freeproccache?

  • Điều gì đã làm cho bộ nhớ cache của thủ tục hết hạn?
  • Nếu các chỉ mục hoặc Thống kê ở ngoài ngày, tại sao truy vấn không tự động biên dịch ?
  • Có thực hành tốt để lên lịch DBCC freeproccache làm JOB không?
  • Có cách nào để xác định các kế hoạch truy vấn ngày có tiềm năng không?
  • Có cách nào để xác định truy vấn vi phạm không?

Mọi trợ giúp đều được đánh giá cao!

+0

Vui lòng xác định phiên bản SQL Server bạn đang sử dụng, ví dụ: [tag: sql-server-2005], [tag: sql-server-2008] ... –

+2

Tất cả 'DBCC freeproccache' làm rỗng bộ đệm thủ tục. Nó sẽ không làm cho số liệu thống kê được cập nhật. Ngược lại nếu số liệu thống kê được tự động cập nhật thì kế hoạch sẽ được biên dịch lại.Tôi giả sử bạn đã có một vấn đề sniffing tham số, nơi kế hoạch đó là trong bộ nhớ cache cho một truy vấn không thích hợp cho tất cả các giá trị tham số có thể. –

+0

Tôi đang sử dụng SQL Server 2005! – user173552

Trả lời

8

Câu hỏi của bạn là tất cả các nơi, vì vậy tôi sẽ cố gắng giải quyết tất cả. Các bộ nhớ cache thủ tục chỉ là quá lớn. Bộ nhớ cache thủ tục của bạn có thể đã được lấp đầy với các kế hoạch sử dụng một lần (điều này không ảnh hưởng đến thống kê, mặc dù số liệu thống kê có thể ảnh hưởng đến bộ nhớ cache của kế hoạch). Bạn có thể đọc rất nhiều chi tiết về các kế hoạch sử dụng một lần trong bài đăng trên blog của Kimberly Tripp, "Plan cache and optimizing for adhoc workloads" - bao gồm truy vấn chống lại sys.dm_exec_cached_plans sẽ giúp xác định thời điểm bộ nhớ cache có nhiều gói sử dụng một lần. Như cô ấy gợi ý, bạn có thể ngăn chặn hiện tượng này bằng cách sử dụng tối ưu hóa cho khối lượng công việc đặc biệt. Nếu bạn đang tìm kiếm cần phải làm điều này thường xuyên, tôi sẽ nói rằng lập kế hoạch freeproccache như một công việc là một ban nhạc viện trợ, không phải là một giải pháp.

Để xóa một gói "không hợp lệ", trước tiên bạn cần phải xác định gói "xấu". Đây có thể là một kế hoạch vượt quá một kích thước nhất định và/hoặc đã không được thực thi trong một thời gian hoặc bạn đã xác định bằng truy vấn dài hạn, v.v. Thật không may khi xác định kế hoạch là nạn nhân của tham số sniffing trừ khi bạn đã biết truy vấn hoặc truy vấn bị ảnh hưởng. Giả sử bạn muốn tìm các gói cũ nhất trong bộ nhớ cache chưa được chạy trong hơn một tuần:

;WITH x AS 
(
    SELECT TOP 10 
     qs.[sql_handle], qs.plan_handle, 
     txs = qs.statement_start_offset, 
     txe = qs.statement_end_offset, 
     [size] = cp.size_in_bytes, 
     [uses] = SUM(cp.usecounts), 
     [last] = MAX(qs.last_execution_time) 
    FROM 
     sys.dm_exec_query_stats AS qs 
    INNER JOIN 
     sys.dm_exec_cached_plans AS cp 
     ON qs.plan_handle = cp.plan_handle 
    WHERE 
     qs.last_execution_time < DATEADD(DAY, -7, CURRENT_TIMESTAMP) 
    GROUP BY 
     qs.[sql_handle], qs.plan_handle, cp.size_in_bytes, 
     qs.statement_start_offset, qs.statement_end_offset 
    ORDER BY 
     [size] DESC 
) 
SELECT 
    x.plan_handle, 
    size, uses, [last], 
    [statement] = COALESCE(NULLIF(
     SUBSTRING(t.[text], x.txs/2, 
      CASE WHEN x.txe = -1 THEN 0 ELSE (x.txe - x.txs)/2 END 
     ), ''), t.[text]) 
FROM x 
CROSS APPLY sys.dm_exec_sql_text(x.[sql_handle]) AS t; 

Bây giờ bạn cần xác minh rằng bạn thực sự muốn xóa gói này. Ví dụ: nếu bạn nhận ra truy vấn đó là điều mà CEO có thể chạy vào ngày mai, có thể tốt nhất là nên để nó ở đó. Nếu bạn muốn xóa kế hoạch, bạn có thể xóa nó trực tiếp bằng cách nói:

DBCC FREEPROCCACHE([paste plan handle from above query here]); 

này nghe có vẻ như làm việc nhiều hơn chạy DBCC FREEPROCCACHE trên toàn cầu, nhưng nếu bạn có rất nhiều kế hoạch tốt trong bộ nhớ cache, nó chắc chắn sẽ tốt hơn cho người dùng của bạn tổng thể.

Tuy nhiên, điều này thực sự giống như một băng trợ giúp. Nếu bộ nhớ đệm của bạn đầy rác và hiệu năng sẽ đi vào nhà vệ sinh cho đến khi bạn giải phóng bộ nhớ đệm, bạn cần xem xét cấp độ cao hơn ở kiến ​​trúc, cách truy vấn được gửi, v.v ... Đây là hành vi tôi mong đợi từ lần lặp đầu tiên của LINQ2SQL, nơi nó sẽ lưu trữ một phiên bản của một kế hoạch cho một truy vấn cho mỗi đối số chuỗi có độ dài khác nhau. Vì vậy, nếu bạn có tham số 'Tháng 1', bạn sẽ nhận được một kế hoạch khác với tham số 'Tháng Hai' vì nó sẽ xác định loại dữ liệu là VARCHAR(7)VARCHAR(8). Khá chắc chắn rằng hành vi là cố định nhưng tôi không biết đủ về môi trường/ứng dụng của bạn để đề xuất nơi chính xác để tìm "ý tưởng tồi".

+0

Bỏ qua tối ưu hóa cho khối lượng công việc đặc biệt - điều này đã được giới thiệu với SQL Server 2008. –

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