【问题标题】:How Can I Log and Find the Most Expensive Queries?如何记录和查找最昂贵的查询?
【发布时间】:2010-09-20 10:48:48
【问题描述】:

sql2k8 中的活动监视器允许我们查看最昂贵的查询。好的,这很酷,但是有没有办法可以记录此信息或通过查询分析器获取此信息?我真的不想打开 Sql 管理控制台并查看活动监视器仪表板。

我想弄清楚哪些查询写得不好/架构设计得不好等等。

非常感谢您的帮助!

【问题讨论】:

    标签: sql-server sql-server-2008 profiling


    【解决方案1】:
    1. 使用 SQL Server Profiler(在 SSMS 的工具菜单上)创建记录这些事件的跟踪:

       RPC:Completed
       SP:Completed
       SP:StmtCompleted
       SQL:BatchCompleted
       SQL:StmtCompleted
      
    2. 您可以从标准跟踪模板开始并对其进行修剪。您没有指定这是针对特定数据库还是整个服务器,如果是针对特定 Db,请包含 DatabaseID 列并将过滤器设置为您的 DB (SELECT DB_ID('dbname'))。确保每个事件都包含逻辑读取数据列。将跟踪设置为记录到文件。如果您要让此跟踪在后台无人看管地运行,最好将最大跟踪文件大小设置为 500MB 或 1GB(如果您有足够的空间)(这完全取决于服务器上有多少活动,所以你必须吮吸它才能看到)。

    3. 先启动跟踪,然后暂停。转到文件->导出->脚本跟踪定义并选择您的数据库版本,然后保存到文件中。您现在有一个 sql 脚本,该脚本创建的跟踪比通过探查器 GUI 运行的开销要少得多。当你运行这个脚本时,它会输出 Trace ID(通常是@ID=2);记下来。

    4. 一旦你有一个跟踪文件 (.trc)(跟踪由于达到最大文件大小而完成,或者你停止了正在运行的跟踪使用

      EXEC sp_trace_setstatus @ID, 0
      执行 sp_trace_setstatus @ID, 2

    您可以将跟踪加载到分析器中,或使用ClearTrace(非常方便)或将其加载到如下表格中:

    SELECT * INTO TraceTable
    FROM ::fn_trace_gettable('C:\location of your trace output.trc', default)
    

    然后你可以运行一个查询来聚合数据,比如这个:

    SELECT COUNT(*) AS TotalExecutions, 
        EventClass, CAST(TextData as nvarchar(2000))
     ,SUM(Duration) AS DurationTotal
     ,SUM(CPU) AS CPUTotal
     ,SUM(Reads) AS ReadsTotal
     ,SUM(Writes) AS WritesTotal
    FROM TraceTable
    GROUP BY EventClass, CAST(TextData as nvarchar(2000))
    ORDER BY ReadsTotal DESC
    

    一旦您确定了代价高昂的查询,您就可以生成并检查实际的执行计划。

    【讨论】:

      【解决方案2】:

      以下脚本为您提供结果。

      SELECT TOP 10 
      SUBSTRING(qt.TEXT, (qs.statement_start_offset/2)+1,
      ((CASE qs.statement_end_offset
      WHEN -1 THEN DATALENGTH(qt.TEXT)
      ELSE qs.statement_end_offset
      END - qs.statement_start_offset)/2)+1),
      qs.execution_count,
      qs.total_logical_reads, 
      qs.last_logical_reads,
      qs.total_logical_writes, qs.last_logical_writes,
      qs.total_worker_time,
      qs.last_worker_time,
      qs.total_elapsed_time/1000000 total_elapsed_time_in_S,
      qs.last_elapsed_time/1000000 last_elapsed_time_in_S,
      qs.last_execution_time,qp.query_plan
      FROM sys.dm_exec_query_stats qs
      CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
      CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
      ORDER BY qs.total_logical_reads DESC 
      

      【讨论】:

      • 这正是我想要的。它很容易创建一个工作来保存它。谢谢。
      • 这是从这里拍摄的吗? => blog.sqlauthority.com/2010/05/14/… 如果是这样的话,还是提一下比较好……
      【解决方案3】:

      我以前从未听说过此工具,但 Microsoft 提供了一组报告,它们可以很好地为您提供准确的信息 - 包括最慢的查询。查看他们的Performance Dashboard Reports

      不确定它们是否与 SQL 2008 兼容,但值得一试。

      【讨论】:

        【解决方案4】:

        SQL Server Profiler 能满足您的需要吗?我还没有使用 2008,所以我不知道该工具是否仍在其中,但如果是,我相信您可以设置跟踪以记录满足特定条件的查询(例如执行和驱动 CPU 的查询)一定的阈值)。

        我们在我们的项目中使用了它,它在帮助我们解决执行不佳的查询方面做得非常好(尽管不要把它留给全时,依靠一般的 Windows 性能计数器来进行性能健康跟踪)。

        【讨论】:

        • hmm.. 我使用了分析器堆,但这并没有总结信息。这是每个查询类型的一行。
        【解决方案5】:

        SQL Server 2008 中有一个新工具Performance Studio,它建立在服务器自动维护的动态管理视图之上,它提供了服务器性能的概览。值得一试。

        【讨论】:

          【解决方案6】:

          (DELL)Quest SQL Optimizer for SQL Server 9.0 引入了 Find SQL 模块,允许用户在您的 SQL Server 中定位资源最密集的 SQL。 https://support.quest.com/softwaredownloads.aspx?pr=268445262

          【讨论】:

            猜你喜欢
            • 2017-12-23
            • 1970-01-01
            • 2018-08-07
            • 2022-01-22
            • 1970-01-01
            • 1970-01-01
            • 2015-06-11
            • 1970-01-01
            • 2023-03-19
            相关资源
            最近更新 更多