人人都是 DBA(XIV)存储过程信息收集脚本汇编

什么?有个 SQL 执行了 8 秒!

哪里出了问题?臣妾不知道啊,得找 DBA 啊。

DBA 人呢?离职了!!擦!!!

程序员在无处寻求帮助时,就得想办法自救,努力让自己变成 "伪 DBA"。

索引

  1. 获取存储过程 SP 执行次数排名
  2. 查看哪个 SP 执行的平均时间最长
  3. 查看哪个 SP 执行的平均时间最不稳定
  4. 查看哪个 SP 耗费了最多的 CPU 时间
  5. 查看哪个 SP 执行的逻辑读最多
  6. 查看哪个 SP 执行的物理读最多
  7. 查看哪个 SP 执行的逻辑写最多

获取存储过程 SP 执行次数排名

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

查看哪个 SP 执行的平均时间最长

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

查看哪个 SP 执行的平均时间最不稳定

复制代码
SELECT TOP (25) p.[name] AS [SP Name]
    ,qs.execution_count
    ,qs.min_elapsed_time
    ,qs.total_elapsed_time / qs.execution_count AS [avg_elapsed_time]
    ,qs.max_elapsed_time
    ,qs.last_elapsed_time
    ,qs.cached_time
FROM sys.procedures AS p WITH (NOLOCK)
INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (NOLOCK) ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
ORDER BY avg_elapsed_time DESC
OPTION (RECOMPILE);
复制代码

查看哪个 SP 耗费了最多的 CPU 时间

复制代码
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(Minute, qs.cached_time, GETDATE()), 0) AS [Calls/Minute]
    ,qs.total_elapsed_time
    ,qs.total_elapsed_time / qs.execution_count AS [avg_elapsed_time]
    ,qs.cached_time
FROM sys.procedures AS p WITH (NOLOCK)
INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (NOLOCK) ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
ORDER BY qs.total_worker_time DESC
OPTION (RECOMPILE);
复制代码

查看哪个 SP 执行的逻辑读最多

复制代码
SELECT TOP (25) p.[name] AS [SP Name]
    ,qs.total_logical_reads AS [TotalLogicalReads]
    ,qs.total_logical_reads / qs.execution_count AS [AvgLogicalReads]
    ,qs.execution_count
    ,ISNULL(qs.execution_count / DATEDIFF(Minute, qs.cached_time, GETDATE()), 0) AS [Calls/Minute]
    ,qs.total_elapsed_time
    ,qs.total_elapsed_time / qs.execution_count AS [avg_elapsed_time]
    ,qs.cached_time
FROM sys.procedures AS p WITH (NOLOCK)
INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (NOLOCK) ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
ORDER BY qs.total_logical_reads DESC
OPTION (RECOMPILE);
复制代码

逻辑读(Logical Read)主要是给 Memory 形成压力,可用于观察比较 Memory 运行情况。

查看哪个 SP 执行的物理读最多

复制代码
SELECT TOP (25) p.[name] AS [SP Name]
    ,qs.total_physical_reads AS [TotalPhysicalReads]
    ,qs.total_physical_reads / qs.execution_count AS [AvgPhysicalReads]
    ,qs.execution_count
    ,qs.total_logical_reads
    ,qs.total_elapsed_time
    ,qs.total_elapsed_time / qs.execution_count AS [avg_elapsed_time]
    ,qs.cached_time
FROM sys.procedures AS p WITH (NOLOCK)
INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (NOLOCK) ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
    AND qs.total_physical_reads > 0
ORDER BY qs.total_physical_reads DESC
    ,qs.total_logical_reads DESC
OPTION (RECOMPILE);
复制代码

物理读(Physical Read)主要是给磁盘 I/O 形成压力,可以用于观察比较 I/O 运行情况。

查看哪个 SP 执行的逻辑写最多

复制代码
SELECT TOP (25) p.[name] AS [SP Name]
    ,qs.total_logical_writes AS [TotalLogicalWrites]
    ,qs.total_logical_writes / qs.execution_count AS [AvgLogicalWrites]
    ,qs.execution_count
    ,ISNULL(qs.execution_count / DATEDIFF(Minute, qs.cached_time, GETDATE()), 0) AS [Calls/Minute]
    ,qs.total_elapsed_time
    ,qs.total_elapsed_time / qs.execution_count AS [avg_elapsed_time]
    ,qs.cached_time
FROM sys.procedures AS p WITH (NOLOCK)
INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (NOLOCK) ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
    AND qs.total_logical_writes > 0
ORDER BY qs.total_logical_writes DESC
OPTION (RECOMPILE);
复制代码

逻辑写(Logical Write)即与 Memory 相关,也与 Disk I/O 相关。通过数据可以判断出写 I/O 最昂贵的存储过程。

 

《人人都是 DBA》系列文章索引:

本系列文章《人人都是 DBA》由 Dennis Gao 发表自博客园,未经作者本人同意禁止任何形式的转载,任何自动或人为的爬虫转载行为均为耍流氓。

posted @   sangmado  阅读(4477)  评论(19编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示