用于UDF性能统计的MS SQL DMV - 如何查找前10个最差的UDF

时间:2011-04-18 15:02:44

标签: sql-server performance user-defined-functions dmv

我听说在Microsoft SQL Server中有多种方法可以找到“最差”的存储过程:执行次数,CPU工作时间,队列等待时间等。

我正在寻找一种方法来查找最差(最慢/最常用)的UDF - 是否有DMV查询?

例如,来自Five DMV Queries That Will Make You a Superhero的此查询按工作时间总计返回前25个缓存的SP,这实际上意味着CPU压力最昂贵的存储过程。

如何为UDF编写类似的内容?

SELECT TOP(25) p.name AS [SP Name], qs.total_worker_time AS [TotalWorkerTime], 
qs.total_worker_time/qs.execution_count AS [AvgWorkerTime], qs.execution_count, 
ISNULL(qs.execution_count/DATEDIFF(Second, qs.cached_time, GETDATE()), 0) AS [Calls/Second],
qs.total_elapsed_time, qs.total_elapsed_time/qs.execution_count 
AS [avg_elapsed_time], qs.cached_time
FROM sys.procedures AS p
INNER JOIN sys.dm_exec_procedure_stats AS qs
ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
ORDER BY qs.total_worker_time DESC OPTION (RECOMPILE);

2 个答案:

答案 0 :(得分:2)

这是找到包含那些语句的对象名称的TOP 100表现最差的SQL语句的另一种方法,例如存储过程,触发器和功能。这在上下文中运行,因此您需要将SSMS切换到要在其上运行的数据库,或者放置USE DB语句。此外,如果重新启动数据库,DMV统计信息将重置,因此它可能会返回“0”行...


SELECT  TOP 100
            [Object_Name] = object_name(st.objectid),
            creation_time, 
            last_execution_time, 
            total_cpu_time = total_worker_time / 1000, 
            avg_cpu_time = (total_worker_time / execution_count) / 1000,
            min_cpu_time = min_worker_time / 1000,
            max_cpu_time = max_worker_time / 1000,
            last_cpu_time = last_worker_time / 1000,
            total_time_elapsed = total_elapsed_time / 1000 , 
            avg_time_elapsed = (total_elapsed_time / execution_count) / 1000, 
            min_time_elapsed = min_elapsed_time / 1000, 
            max_time_elapsed = max_elapsed_time / 1000, 
            avg_physical_reads = total_physical_reads / execution_count,
            avg_logical_reads = total_logical_reads / execution_count,
            execution_count, 
            SUBSTRING(st.text, (qs.statement_start_offset/2) + 1,
                  (
                        (
                              CASE statement_end_offset
                                    WHEN -1 THEN DATALENGTH(st.text)
                                    ELSE qs.statement_end_offset
                              END 
                              - qs.statement_start_offset
                        ) /2
                  ) + 1
            ) as statement_text
FROM 
            sys.dm_exec_query_stats qs
CROSS APPLY 
            sys.dm_exec_sql_text(qs.sql_handle) st
WHERE
            Object_Name(st.objectid) IS NOT NULL
            AND st.dbid = DB_ID()
ORDER BY 
            db_name(st.dbid), 
            total_worker_time / execution_count  DESC


答案 1 :(得分:2)

试试这个。

上述代码仅限于存储过程

注意:没有“sys.functions”