【问题标题】:How to check which stored procedure is taking maximum time in sql server如何检查哪个存储过程在sql server中花费最大时间
【发布时间】:2011-03-28 06:20:16
【问题描述】:

我想知道有哪些方法可以监控我的哪些存储过程和 SQL 查询在各种组件(CPU 周期、扫描时间等)上花费的时间超过了已设置的阈值。

我也希望它被记录下来。 每当任何用户使用我的网站并调用某个程序时,我都想记录所有超过我阈值的程序。

是否可以使用 SQL 查询或过程来完成。我们有这方面的一些程序吗? 任何 SQL 工具或任何外部工具,都可以付费(试用)或免费。我想在我的数据库上试用它们。

【问题讨论】:

  • 什么版本的 SQL Server?
  • 我正在使用 Sql Server 2005,amy 在 2008 年也需要这样做
  • 啊,对于 SQL Server 2008,您也可以使用扩展事件,但不能在 2005 上使用。

标签: sql-server performance optimization


【解决方案1】:

您应该能够使用Dynamic Management Views (DMV) 来执行此操作,尤其是您可能对维护所有查询(CPU 时间、物理/逻辑读取等)的执行统计信息的exec_query_stats 视图最感兴趣。 ..) 按执行计划分组。

另请参阅这篇出色的文章,其中包含用于查看计划统计信息的示例查询,并详细介绍了该主题:

最后,如果您想跟踪/记录过度长时间运行的查询,那么您可能需要考虑让 SQL Server Profiler 跟踪始终运行,并将执行时间过滤器设置为一些高数字(例如 > 1000 ms)。您可以使用 SQL Server Profiler Windows 应用程序,也可以使用 T-SQL 创建跟踪,并将其记录到数据库中的表中:

这样做的好处是可以准确地告诉您哪个查询需要多长时间、何时以及该查询的参数是什么(神圣的 SQL 蝙蝠侠!)

在加载的数据库上运行此跟踪实际上对性能的影响非常小 - 我知道一些令人惊讶的关键应用程序会将这些跟踪作为例行程序运行,以便能够快速诊断性能问题(这确实有帮助很多)。关键是选择一个“大”的执行时间,它足够大,不会淹没日志,但又足够小,可以提取足够长的运行查询以发挥作用。

过去在遇到性能问题时使用的另一个技巧是让未经过滤的 SQL Server 跟踪在加载的 SQL Server 上运行一小段时间(1 分钟左右)(它确实几乎没有效果,你只会被日志淹没)

我也衷心地推荐Microsoft SQL Server internals关于这个主题的书籍 - 它非常技术性,但它非常出色,因为它不仅涵盖了这些类型的诊断工具,而且还涵盖了它们实际上意思是

【讨论】:

  • Google 上有大量关于如何使用动态管理视图从 SQL 服务器中提取各种性能信息的信息。
  • DMV 上的一个主要问题 - 只要项目保留在缓存中,它就会起作用。繁忙的系统,可能不会留在缓存中。我们每隔几个小时定期捕获数据,然后使用 MERGE 来确保 任何 调用都保存在我们的汇总表中。但不要相信它会留在缓存和 DMV 中。因此,正如贾斯汀所说,您仅限于准系统跟踪或准系统 XE。
【解决方案2】:

如果您有 SQL 2005 + 您可以在管理报告中运行标准报告 右键单击​​管理工作室中的数据库并选择对象执行统计信息 - 这仅在上次重新启动后才有效。您也可以使用 DMV 的 sys.dm_exec_query_stats 进行查询

如果您使用的是旧版本的 SQL,请使用 SQL Server Profiler,这将向您显示执行时间、读取、cpu、写入,您可以过滤其中任何一个的阈值。

【讨论】:

    【解决方案3】:

    这些是我通常使用的。我不记得我从哪里得到它们的,但它们很管用。这是用于运行时间最长的查询:

    SELECT TOP 100
        qs.total_elapsed_time / qs.execution_count / 1000000.0 AS average_seconds,
        qs.total_elapsed_time / 1000000.0 AS total_seconds,
        qs.execution_count,
        SUBSTRING (qt.text,qs.statement_start_offset/2, 
             (CASE WHEN qs.statement_end_offset = -1 
                THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2 
              ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) AS individual_query,
        o.name AS object_name,
        DB_NAME(qt.dbid) AS database_name
    FROM sys.dm_exec_query_stats qs
        CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
        LEFT OUTER JOIN sys.objects o ON qt.objectid = o.object_id
    WHERE qt.dbid = DB_ID()
    ORDER BY average_seconds DESC;
    

    ...这个给出了使用最多 I/O 的查询列表:

    SELECT TOP 100
        (total_logical_reads + total_logical_writes) / qs.execution_count AS average_IO,
        (total_logical_reads + total_logical_writes) AS total_IO,
        qs.execution_count AS execution_count,
        SUBSTRING (qt.text,qs.statement_start_offset/2, 
             (CASE WHEN qs.statement_end_offset = -1 
                THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2 
              ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) AS individual_query,
        o.name AS object_name,
        DB_NAME(qt.dbid) AS database_name
    FROM sys.dm_exec_query_stats qs
        CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
        LEFT OUTER JOIN sys.objects o ON qt.objectid = o.object_id
    WHERE qt.dbid = DB_ID()
    ORDER BY average_IO DESC;
    

    希望这些对您有所帮助!

    【解决方案4】:

    您可以使用 SQL Server Profiler:

    1. 创建一个新的跟踪。
    2. 选择你想要的服务器
    3. 选择模板“空白”
    4. 在“事件选择”选项卡中,选择 'SP:Completed'(在存储下 程序)
    5. 打开所需的列
    6. 在列过滤器中,选择持续时间 并为“大于”输入一个值 或等于'(注意单位 如上所述;要么 毫秒或微秒)。这是您的“门槛”
    7. 点击“运行”

    备注:

    • 这不包括加载 SP 的时间;如果 你的 SP 非常大,那将 添加到上述时间
    • 我偶尔会遇到问题 持续时间值;如果你有 有问题,你可能想 datediff 结束/开始时间

    【讨论】:

      【解决方案5】:

      在付费工具方面,我强烈推荐来自Confio SoftwareIgnite for SQL Server。您可以下载免费试用版并试一试。我们已经使用它大约 2 年了,并且对结果非常满意。在我们的例子中,我们挑选了几个“低悬的果实”存储过程,我们在运行演示时优化了这些存储过程以快速获胜。这足以让我们相信这是一项值得的投资。

      【讨论】:

        【解决方案6】:

        另请注意,在 SQL 2008 中,有一个专门用于过程的新 DMV:sys.dm_exec_procedure_stats。此视图将为您提供整个过程的累积统计信息,包括执行非查询相关工作(如 WAITFOR、函数调用和条件逻辑)所花费的时间和 CPU。

        在您的生产服务器上运行探查器跟踪时请务必小心。跟踪在服务器上引入了开销,甚至是最小的跟踪。根据您的服务器的繁忙程度,这实际上可能很明显。向跟踪定义添加过滤器并不能减少这种开销,SQL Server 仍然需要处理每个触发的事件以确定它是否满足过滤条件。过滤仅用于减小跟踪文件的大小。

        如果您正在处理 SQL 2008,您可能想要研究的另一个工具是数据收集器和管理数据仓库。这是 SQL Server 附带的工具(无需额外费用),可让您定期收集查询统计信息并将其上传到数据仓库。它带有内置的收集器和报告,非常全面,可以满足最常见的监控需求。

        http://msdn.microsoft.com/en-us/library/dd939169(SQL.100).aspx

        在上面提到的所有内容中,我认为您最好的选择是 sys.dm_exec_query_stats,因为它开销低、免费且可用于 SQL 2005 和 SQL 2008。

        【讨论】:

          【解决方案7】:

          a recent SO question 的获奖答案中,这将为您提供前 50 个最常用的过程和过程中的语句。您可以将 TOP 50 更改为 TOP 1 或您希望看到的任何其他数字。

          SELECT TOP 50 *
          FROM ( SELECT COALESCE(OBJECT_NAME(s2.objectid), 'Ad-Hoc') AS ProcName
                     ,execution_count
                     ,s2.objectid
                     ,( SELECT TOP 1 SUBSTRING(s2.text,
                                               statement_start_offset / 2 + 1,
                                               ( ( CASE WHEN statement_end_offset = -1
                                                        THEN ( LEN(CONVERT(NVARCHAR(MAX), s2.text))
                                                               * 2 )
                                                        ELSE statement_end_offset
                                                   END ) - statement_start_offset )
                                               / 2 + 1)
                      ) AS sql_statement
                     ,last_execution_time
                  FROM sys.dm_exec_query_stats AS s1
                  CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS s2
               ) x
          WHERE sql_statement NOT LIKE 'SELECT * FROM(SELECT coalesce(object_name(s2.objectid)%'
              AND OBJECTPROPERTYEX(x.objectid, 'IsProcedure') = 1
              AND EXISTS ( SELECT 1
                              FROM sys.procedures s
                              WHERE s.is_ms_shipped = 0
                                  AND s.name = x.ProcName )
          ORDER BY execution_count DESC
          

          您可以定期运行它以查看随时间发生的变化。 将其放入存储过程并将结果插入日志表。设置计划作业以固定间隔运行该存储过程。

          【讨论】:

            【解决方案8】:

            如果您使用的是 SQL Server 2008,您可以尝试使用资源调控器来控制和监控 CPU 和内存工作负载。

            出于记录目的,您可以使用Data Collection。您可以创建自定义收集集,从任何 DMV 收集快照并将其上传到性能数据仓库。

            Idera 具有图表工具,可显示每个查询的资源消耗。我认为它也允许用户设置阈值和电子邮件警报。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-09-26
              • 1970-01-01
              相关资源
              最近更新 更多