Trong khi tôi, như @Thomas, hoàn toàn đồng ý với @Aaron trong các nhận xét về câu hỏi liên quan đến mối quan tâm về "sử dụng CPU trên cơ sở dữ liệu" là chính xác hay hữu ích, ít nhất tôi có thể trả lời câu hỏi tại sao hai truy vấn đó lại như vậy khác nhau. Và lý do tại sao chúng khác nhau sẽ chỉ ra cái nào chính xác hơn, mặc dù mức độ chính xác cao hơn vẫn tương đối với cái không chính xác, do đó vẫn không thực sự chính xác ;-).
Truy vấn đầu tiên sử dụng sys.dm_exec_query_stats để lấy thông tin CPU (tức là total_worker_time
). Nếu bạn đi đến trang được liên kết là tài liệu MSDN cho DMV đó, bạn sẽ thấy một đoạn giới thiệu ngắn, 3 câu và 2 trong số những câu đó cho chúng ta hầu hết những gì chúng ta cần để hiểu ngữ cảnh của thông tin này ("nó đáng tin cậy đến mức nào" và "làm thế nào để nó so sánh với sys.sysprocesses
"). Hai câu đó là:
Trả về thống kê hiệu suất tổng hợp cho các gói truy vấn được lưu trong bộ đệm SQL Server. ... Khi một gói được xóa khỏi bộ đệm, các hàng tương ứng sẽ bị loại khỏi chế độ xem này
Câu đầu tiên, "Trả về thống kê hiệu suất tổng hợp ", cho chúng tôi biết rằng thông tin trong DMV này (giống như một số thông tin khác) được tích lũy và không cụ thể cho chỉ các truy vấn hiện đang chạy. Điều này cũng được chỉ định bởi một trường trong DMV không phải là một phần của truy vấn trong Câu hỏi, execution_count
một lần nữa cho thấy đây là dữ liệu tích lũy. Và nó khá thuận tiện để dữ liệu này được tích lũy khi bạn có thể lấy trung bình, v.v. bằng cách chia một số số liệu cho execution_count
.
Câu thứ hai, "các kế hoạch bị xóa khỏi bộ đệm cũng bị xóa khỏi DMV này", chỉ ra rằng đó hoàn toàn không phải là một bức tranh hoàn chỉnh, đặc biệt là nếu máy chủ đã có bộ đệm kế hoạch khá đầy đủ và đang được tải và do đó hết hạn hơi thường xuyên Ngoài ra, hầu hết các DMV được đặt lại khi máy chủ đặt lại để chúng không phải là lịch sử thực sự ngay cả khi các hàng này không bị xóa khi hết hạn gói.
Bây giờ hãy tương phản ở trên với sys.sysprocesses
. Chế độ xem hệ thống này chỉ hiển thị những gì hiện đang chạy, giống như sự kết hợp của sys.dm_exec_connections , sys.dm_exec_sments và sys.dm_exec numquests (được nêu trên trang được liên kết cho sys.dm_exec_sessions
). Đây là một cái nhìn hoàn toàn khác về máy chủ so vớisys.dm_exec_query_stats
DMV giữ dữ liệu ngay cả khi quá trình hoàn tất. Có nghĩa là, liên quan đến "kết quả từ truy vấn thứ hai có sai không?" câu hỏi, họ không sai, họ chỉ liên quan đến một khía cạnh khác (tức là khung thời gian) của các số liệu thống kê hiệu suất.
Vì vậy, truy vấn sử dụng sys.sysprocesses
chỉ nhìn vào "ngay bây giờ". Và truy vấn sử dụng sys.dm_exec_query_stats
đang xem xét hầu hết (có thể) những gì đã xảy ra kể từ lần khởi động lại cuối cùng của dịch vụ SQL Server (hoặc rõ ràng là khởi động lại hệ thống). Đối với phân tích hiệu suất chung có vẻ như sys.dm_exec_query_stats
tốt hơn nhiều, nhưng một lần nữa, nó giảm thông tin hữu ích mọi lúc. Và, trong cả hai trường hợp, bạn cũng cần xem xét các điểm được tạo bởi @Aaron trong các nhận xét câu hỏi (đã bị xóa) về độ chính xác của giá trị "cơ sở dữ liệu" ở vị trí đầu tiên (nghĩa là nó chỉ phản ánh DB hoạt động đã khởi tạo mã , không nhất thiết là nơi "vấn đề" đang xảy ra).
Tuy nhiên, nếu bạn chỉ cần / muốn có được một cảm giác về những gì đang xảy ra ngay bây giờ trên tất cả các cơ sở dữ liệu, có thể vì những thứ đang chậm lại ngay bây giờ, bạn nên sử dụng sự kết hợp của sys.dm_exec_connections
, sys.dm_exec_sessions
và sys.dm_exec_requests
(và không phải là bị phản đối sys.sysprocesses
). Chỉ cần lưu ý rằng bạn đang xem / tìm kiếm truy vấn , không phải cơ sở dữ liệu , bởi vì các truy vấn có thể tham gia trên nhiều cơ sở dữ liệu, bao gồm UDF từ một hoặc nhiều cơ sở dữ liệu, v.v.
EDIT:
Nếu mối quan tâm chung là làm giảm người tiêu dùng CPU cao, thì hãy tìm các truy vấn chiếm nhiều CPU nhất, vì cơ sở dữ liệu không thực sự chiếm CPU (tìm kiếm trên mỗi cơ sở dữ liệu có thể hoạt động tại một công ty lưu trữ, nơi mỗi cơ sở dữ liệu được cách ly và thuộc sở hữu của một khách hàng khác nhau).
Truy vấn sau đây sẽ giúp xác định các truy vấn có mức sử dụng CPU trung bình cao. Nó ngưng tụ dữ liệu trong query_stats DMV vì các bản ghi đó có thể hiển thị cùng một truy vấn (có, cùng một tập hợp con của lô truy vấn) nhiều lần, mỗi lần có một kế hoạch thực hiện khác nhau.
;WITH cte AS
(
SELECT stat.[sql_handle],
stat.statement_start_offset,
stat.statement_end_offset,
COUNT(*) AS [NumExecutionPlans],
SUM(stat.execution_count) AS [TotalExecutions],
((SUM(stat.total_logical_reads) * 1.0) / SUM(stat.execution_count)) AS [AvgLogicalReads],
((SUM(stat.total_worker_time) * 1.0) / SUM(stat.execution_count)) AS [AvgCPU]
FROM sys.dm_exec_query_stats stat
GROUP BY stat.[sql_handle], stat.statement_start_offset, stat.statement_end_offset
)
SELECT CONVERT(DECIMAL(15, 5), cte.AvgCPU) AS [AvgCPU],
CONVERT(DECIMAL(15, 5), cte.AvgLogicalReads) AS [AvgLogicalReads],
cte.NumExecutionPlans,
cte.TotalExecutions,
DB_NAME(txt.[dbid]) AS [DatabaseName],
OBJECT_NAME(txt.objectid, txt.[dbid]) AS [ObjectName],
SUBSTRING(txt.[text], (cte.statement_start_offset / 2) + 1,
(
(CASE cte.statement_end_offset
WHEN -1 THEN DATALENGTH(txt.[text])
ELSE cte.statement_end_offset
END - cte.statement_start_offset) / 2
) + 1
)
FROM cte
CROSS APPLY sys.dm_exec_sql_text(cte.[sql_handle]) txt
ORDER BY cte.AvgCPU DESC;
AvgCPU
bằng mili giây?