Ngày chạy cuối cùng trên một thủ tục được lưu trữ trong SQL Server


77

Chúng tôi bắt đầu nhận được rất nhiều thủ tục được lưu trữ trong ứng dụng của mình. Nhiều người trong số họ dành cho các báo cáo tùy chỉnh, nhiều trong số đó không còn được sử dụng. Có ai biết về một truy vấn mà chúng tôi có thể chạy trên các dạng xem hệ thống trong SQL Server 2005 sẽ cho chúng tôi biết ngày cuối cùng một thủ tục được lưu trữ được thực thi không?


2
Chúng tôi có tất cả nhật ký Sprocs của chúng tôi mà chúng đã được gọi. Tất cả các Sprocs của chúng tôi đều có tham số cho ID phiên và thông số đó được đưa vào nhật ký (cùng với bất kỳ lỗi nào được nâng lên và thời lượng). Chúng tôi đã cảm thấy thoải mái (cho đến nay!) Với trên không, và nó đã giúp với báo cáo gỡ lỗi / quản lý thường
Kristen

Câu trả lời:


36

Tóm lại, không.

Tuy nhiên, có những điều "tốt đẹp" bạn có thể làm.

  1. Chạy theo dõi hồ sơ với tên chương trình được lưu trữ
  2. Thêm một dòng cho mỗi proc (tất nhiên là tạo một tabel)
    • " INSERT dbo.SPCall (What, When) VALUES (OBJECT_NAME(@@PROCID), GETDATE()"
  3. Kéo dài 2 với thời lượng quá

Có những điều "thú vị" bạn có thể làm:

  1. Xóa nó, xem ai gọi
  2. Xóa quyền, xem ai gọi
  3. Thêm RAISERROR ('Warning: pwn3d: call admin', 16, 1), xem ai gọi
  4. Thêm WAITFOR DELAY '00:01:00', xem ai gọi

Bạn có được ý tưởng. Phương pháp hỗ trợ CNTT "xem ai gọi" đã được thử nghiệm và thử nghiệm.

Nếu báo cáo là Dịch vụ báo cáo, thì bạn có thể khai thác cơ sở dữ liệu RS để chạy báo cáo nếu bạn có thể khớp mã để báo cáo DataSet.

Dù sao thì bạn cũng không thể dựa vào DMV vì chúng được đặt lại om SQL Server khởi động lại. Bộ nhớ cache / khóa truy vấn là tạm thời và không tồn tại trong bất kỳ khoảng thời gian nào.


Lần đầu tiên tôi sử dụng "xem ai gọi" để tìm các cổng phụ trên bộ điều khiển thiết bị đầu cuối.
Chris Catignani

50

Đoạn mã dưới đây sẽ thực hiện thủ thuật (> = 2008)

SELECT o.name, 
       ps.last_execution_time 
FROM   sys.dm_exec_procedure_stats ps 
INNER JOIN 
       sys.objects o 
       ON ps.object_id = o.object_id 
WHERE  DB_NAME(ps.database_id) = '' 
ORDER  BY 
       ps.last_execution_time DESC  

Chỉnh sửa 1: Hãy ghi lại lời khuyên của Jeff Modens bên dưới. Nếu bạn tìm thấy một thủ tục ở đây, bạn có thể chắc chắn rằng nó là chính xác. Nếu bạn không làm vậy thì bạn chỉ không biết - bạn không thể kết luận rằng nó không chạy.


1 một kịch bản rất hữu ích, cảm ơn, một sự điều chỉnh nhỏ, trong dòng thứ hai bạn bỏ lỡ một 'e', nó phải là a.last_execution_time,
AmmarR

1
Cảm ơn và +1 cho điều này. DMV rất hữu ích. chúng ta có thể nhận được các thông số đầu vào được cung cấp của thủ tục không?
Neeraj Prasad Sharma

3
Đẹp. Tôi giả sử rằng WHERE DB_NAME(ps.database_id) = ''chúng ta nên điền vào chỗ trống với tên cơ sở dữ liệu của chúng ta.
Baodad

Nó không hiển thị tất cả các chương trình thủ tục lưu trữ chỉ chạy cuối cùng thủ tục lưu trữ

30

Oh, hãy cẩn thận ngay bây giờ! Tất cả mà ngỡ là vàng! Tất cả các chế độ xem và chức năng dm “thống kê” đều có vấn đề đối với loại điều này. Chúng chỉ hoạt động dựa trên những gì có trong bộ nhớ cache và thời gian tồn tại của những gì trong bộ nhớ cache có thể được đo bằng vài phút. Nếu bạn sử dụng một thứ như vậy để xác định SP nào là ứng cử viên bị loại bỏ, bạn có thể rơi vào thế giới bị tổn thương khi xóa SP đã được sử dụng chỉ vài phút trước.

Các đoạn trích sau đây là từ Sách Trực tuyến cho các lượt xem dm nhất định…

sys.dm_exec_procedure_stats Trả về thống kê hiệu suất tổng hợp cho các thủ tục đã lưu trong bộ nhớ cache. Dạng xem chứa một hàng cho mỗi thủ tục được lưu trữ và thời gian tồn tại của hàng miễn là thủ tục được lưu trữ vẫn được lưu trong bộ nhớ cache. Khi một thủ tục đã lưu trữ bị xóa khỏi bộ đệm, hàng tương ứng sẽ bị loại bỏ khỏi dạng xem này.

sys.dm_exec_query_stats Chế độ xem chứa một hàng cho mỗi câu lệnh truy vấn trong kế hoạch được lưu trong bộ nhớ cache và thời gian tồn tại của các hàng được gắn với chính kế hoạch. Khi một kế hoạch bị xóa khỏi bộ nhớ cache, các hàng tương ứng sẽ bị loại bỏ khỏi chế độ xem này.


3
Vì vậy, sẽ công bằng khi nói rằng nếu một mục nhập xuất hiện trong truy vấn do @Pixelated cung cấp thì thời gian thực hiện cuối cùng là chính xác, nhưng nếu mục nhập bị thiếu thì bạn không thể đưa ra giả định về thời gian thực hiện cuối cùng của nó?
Sir Crispalot

6
Tôi xin lỗi vì câu trả lời rất muộn. Gần đây tôi không ở đây nhiều. Những gì bạn nêu ở trên là đúng.
Jeff Moden

8

sys.dm_exec_procedure_stats chứa thông tin về các hàm thực thi, các ràng buộc và Thủ tục, v.v. Nhưng thời gian tồn tại của hàng có giới hạn, Thời điểm kế hoạch thực thi bị xóa khỏi bộ đệm, mục nhập sẽ biến mất.

Use [yourDatabaseName]
GO
SELECT  
        SCHEMA_NAME(sysobject.schema_id),
        OBJECT_NAME(stats.object_id), 
        stats.last_execution_time
    FROM   
        sys.dm_exec_procedure_stats stats
        INNER JOIN sys.objects sysobject ON sysobject.object_id = stats.object_id 
    WHERE  
        sysobject.type = 'P'
    ORDER BY
           stats.last_execution_time DESC  

Thao tác này sẽ cung cấp cho bạn danh sách các thủ tục được thực hiện gần đây.

Nếu bạn muốn kiểm tra xem một thủ tục lưu trữ perticular được thực thi gần đây hay không

SELECT  
    SCHEMA_NAME(sysobject.schema_id),
    OBJECT_NAME(stats.object_id), 
    stats.last_execution_time
FROM   
    sys.dm_exec_procedure_stats stats
    INNER JOIN sys.objects sysobject ON sysobject.object_id = stats.object_id 
WHERE  
    sysobject.type = 'P'
    and (sysobject.object_id = object_id('schemaname.procedurename') 
    OR sysobject.name = 'procedurename')
ORDER BY
       stats.last_execution_time DESC  

4

Nếu bạn bật Cửa hàng truy vấn trên SQL Server 2016 hoặc mới hơn, bạn có thể sử dụng truy vấn sau để thực hiện SP cuối cùng. Lịch sử phụ thuộc vào Cấu hình cửa hàng truy vấn.

SELECT 
      ObjectName = '[' + s.name + '].[' + o.Name  + ']'
    , LastModificationDate  = MAX(o.modify_date)
    , LastExecutionTime     = MAX(q.last_execution_time)
FROM sys.query_store_query q 
    INNER JOIN sys.objects o
        ON q.object_id = o.object_id
    INNER JOIN sys.schemas s
        ON o.schema_id = s.schema_id
WHERE o.type IN ('P')
GROUP BY o.name , + s.name 

1

Điều này hoạt động tốt vào năm 2005 (nếu kế hoạch nằm trong bộ nhớ cache)

USE YourDb;

SELECT qt.[text]          AS [SP Name],
       qs.last_execution_time,
       qs.execution_count AS [Execution Count]
FROM   sys.dm_exec_query_stats AS qs
       CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
WHERE  qt.dbid = DB_ID()
       AND objectid = OBJECT_ID('YourProc') 

1

Tôi sử dụng cái này:

use YourDB;

SELECT 
    object_name(object_id), 
    last_execution_time, 
    last_elapsed_time, 
    execution_count
FROM   
     sys.dm_exec_procedure_stats ps 
where 
      lower(object_name(object_id)) like 'Appl-Name%'
order by 1
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.