原文:通过SQL Server的扩展事件来跟踪SQL语句在运行时,时间都消耗到哪儿了?


问题就是,一个很简单的语句,在不同的服务器上执行,所需要的时间相差很大,特别提到在性能差的服务器上反而快,在性能好的服务器上反而慢,他想知道这是为什么?

对这个问题,我的回答是:

从表面看,很难分析出为什么多台机器执行同一个简单的sql语句,速度有差异,甚至好的服务器反而花了更多的时间,而看上去相对较差的机器反而更快,这些都是表面现象。

我们可以分析一下整个SQL语句执行的大致过程:

1、语句发送到SQL Server服务器端。

2、SQL Server会找这个语句是否已经缓存在内存中,如果能找到,这样就不用重新编译,这样就会节省时间。

如果不在缓存中,那么就需要经过语法检查、语义检查、权限检查、编译,这个过程需要内存;再进行优化,生成执行计划,优化时也需要内存;然后把这个执行计划放进行缓存,这个也需要内存。

3、在执行的时候,如果所要访问的数据都在内存,也就是数据也缓存在内存中了,那么就不用从硬盘读取数据,也就是没有物理IO,只有逻辑操作,速度也会快。

4、在执行的时候,需要申请相关锁,如果所要访问的数据上已经加了锁,那么需要等待。

5、上面几点中,还有一个问题是,系统的负载,如果系统本来就很忙,那么上面的整个过程,可能任何一步,都有可能会等待一会。另外,内存和IO非常重要,如果你的系统存在内存压力,此外,磁盘经常满负荷运转,那么计算是执行一个简单的语句,也会比负载比较低时慢。

你的开发机器和你的服务器,负载是否一样。

6、非常重要的一点,语句运行完成后的结果集,通过网络发送到客户端程序,所以网络是否通畅以及速度的快慢,决定了你的语句的快慢。

对比,你的多张图片,之所以慢的原因应该不是在分析编译、执行时的cpu时间,而是执行时的占用时间,应该是花在IO上的,扫描次数和逻辑读取次数都一样,lob的逻辑读取差了2个,lob预读次数一样,很有可能就是这点差别,当然还有系统的负载,也会导致从硬盘读数据变慢。

另外,如果是直接连接远程,可能会有网络问题,如果是像你上面,直接通过远程连接登录到数据库服务器,再直接连数据库,那么应该不是网络的问题。

下面通过 这个帖子所描述的方法: http://blogs.msdn.com/b/sqlsakthi/archive/2011/02/20/sql-query-slowness-troubleshooting-using-extended-events-wait-info-event.aspx

通过扩展事件来跟踪一个语句,在运行时到底把时间消耗在哪儿了,比如说是PAGEIOLATCH_EX。

1、建立扩展事件,注意下面的session_id为你要跟踪的语句的会话id,要改过来。


  1. -- *** Change the Session ID values as per your need ***
  2. -- Check for existing session
  3. IF EXISTS(SELECT * FROM sys.server_event_sessions WHERE name='Waits_of_Particular_Session')
  4. DROP EVENT session Waits_of_Particular_Session ON SERVER;
  5. GO
  6. -- Create a session and add events and actions
  7. CREATE EVENT SESSION Waits_of_Particular_Session
  8. ON SERVER
  9. ADD EVENT sqlserver.sql_statement_starting
  10. (
  11. ACTION (sqlserver.session_id,
  12. sqlserver.sql_text,
  13. sqlserver.plan_handle)
  14. WHERE
  15. sqlserver.session_id > 52 AND sqlserver.session_id < 54
  16. ),
  17. ADD EVENT sqlos.wait_info
  18. (
  19. ACTION (sqlserver.session_id,
  20. sqlserver.sql_text,
  21. sqlserver.plan_handle)
  22. WHERE
  23. sqlserver.session_id > 52 AND sqlserver.session_id < 54
  24. ),
  25. ADD EVENT sqlos.wait_info_external
  26. (
  27. ACTION (sqlserver.session_id,
  28. sqlserver.sql_text,
  29. sqlserver.plan_handle)
  30. WHERE
  31. sqlserver.session_id > 52 AND sqlserver.session_id < 54
  32. ),
  33. ADD EVENT sqlserver.sql_statement_completed
  34. (
  35. ACTION (sqlserver.session_id,
  36. sqlserver.sql_text,
  37. sqlserver.plan_handle)
  38. WHERE
  39. sqlserver.session_id > 52 AND sqlserver.session_id < 54
  40. )
  41. ADD TARGET package0.asynchronous_file_target
  42. (SET filename=N'C:\Temp\Waits_of_Particular_Session.xel')
  43. WITH (MAX_DISPATCH_LATENCY = 5 SECONDS, EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS, TRACK_CAUSALITY=ON)
  44. GO
  45. -- Start the Session
  46. ALTER EVENT SESSION Waits_of_Particular_Session ON SERVER
  47. STATE = START
  48. GO
  49. -- Run the query from the SPID
  50. -- Code to stop the session once the query execution completes
  51. ALTER EVENT SESSION Waits_of_Particular_Session ON SERVER
  52. STATE = STOP
  53. GO

2、然后,运行你的语句:select  *  from  dbo.ttt

3、最后,运行下面的语句,获取各类操作所消耗的时间:


  1. -- Parse the XML to show wait details
  2. SELECT
  3. event_xml.value('(./@name)', 'varchar(1000)') as Event_Name,
  4. event_xml.value('(./data[@name="wait_type"]/text)[1]', 'nvarchar(max)') as Wait_Type,
  5. event_xml.value('(./data[@name="duration"]/value)[1]', 'int') as Duration,
  6. event_xml.value('(./data[@name="opcode"]/text)[1]', 'varchar(100)') as Operation,
  7. event_xml.value('(./action[@name="session_id"]/value)[1]', 'int') as SPID,
  8. event_xml.value('(./action[@name="sql_text"]/value)[1]', 'nvarchar(max)') as TSQLQuery,
  9. event_xml.value('(./action[@name="plan_handle"]/value)[1]', 'nvarchar(max)') as PlanHandle
  10. FROM
  11. (SELECT CAST(event_data AS XML) xml_event_data FROM sys.fn_xe_file_target_read_file('C:\Temp\Waits_of_Particular_Session*.xel', 'C:\Temp\Waits_of_Particular_Session*.xem', NULL, NULL)) AS event_table
  12. CROSS APPLY xml_event_data.nodes('//event') n (event_xml)
  13. WHERE
  14. event_xml.value('(./@name)', 'varchar(1000)') IN ('wait_info','wait_info_external')
  15. -- Code to drop the session
  16. DROP EVENT SESSION Waits_of_Particular_Session ON SERVER;

这段监控的语句,在网友的服务器上执行,最后发现,时间主要消耗在了NETWORK_IO上,也就是网络。

发布了416 篇原创文章 · 获赞 135 · 访问量 94万+

通过SQL Server的扩展事件来跟踪SQL语句在运行时,时间都消耗到哪儿了?的更多相关文章

  1. SQL Server代理(5/12):理解SQL代理错误日志

    SQL Server代理是所有实时数据库的核心.代理有很多不明显的用法,因此系统的知识,对于开发人员还是DBA都是有用的.这系列文章会通俗介绍它的很多用法. 如我们在这个系列的前几篇文章所见,SQL ...

  2. SQL Server中存储过程比直接运行SQL语句慢的原因

    原文:SQL Server中存储过程比直接运行SQL语句慢的原因 在很多的资料中都描述说SQLSERVER的存储过程较普通的SQL语句有以下优点: 1.       存储过程只在创造时进行编译即可,以 ...

  3. Configure Always On Availability Group for SQL Server on Ubuntu——Ubuntu上配置SQL Server Always On Availability Group

    下面简单介绍一下如何在Ubuntu上一步一步创建一个SQL Server AG(Always On Availability Group),以及配置过程中遇到的坑的填充方法. 目前在Linux上可以搭 ...

  4. SQL Server中一些有用的日期sql语句

    SQL Server中一些有用的日期sql语句 1.一个月第一天的 SELECT DATEADD(mm, DATEDIFF(mm,0,getdate()), 0) 2.本周的星期一 SELECT DA ...

  5. SQL Server温故系列(5):SQL 查询之分组查询 GROUP BY

    1.GROUP BY 与聚合函数 2.GROUP BY 与 HAVING 3.GROUP BY 扩展分组 3.1.GROUP BY ROLLUP 3.2.GROUP BY CUBE 3.3.GROUP ...

  6. SQL Server定时自动抓取耗时SQL并归档数据发邮件脚本分享

    SQL Server定时自动抓取耗时SQL并归档数据发邮件脚本分享 第一步建库和建表 USE [master] GO CREATE DATABASE [MonitorElapsedHighSQL] G ...

  7. [转]SQL SERVER – Importance of Database Schemas in SQL Server

    原文地址http://blog.sqlauthority.com/2009/09/07/sql-server-importance-of-database-schemas-in-sql-server/ ...

  8. 安装 SQL Server 2008 时提示需要删除 SQL Server 2005 Express 工具

    已安装 SQL Server 2005,安装 SQL Server 2008 时提示需要删除 SQL Server 2005 Express 工具 错误提示:已安装 SQL Server 2005 E ...

  9. SQL SERVER 2008配置Database Mail –用SQL 数据库发邮件

    SQL SERVER 2008配置Database Mail –用SQL  数据库发邮件 https://blogs.msdn.microsoft.com/apgcdsd/2011/06/28/sql ...

随机推荐

  1. Centos 7 下 Corosync + Pacemaker + DRBD + psc + crmsh 实现 mysql 服务高可用

    一.介绍 高可用,大家可能会想到比较简单的Keepalived,或者更早一点的 heartbeat,也可能会用到 Corosync+Pacemaker,那么他们之间有什么区别. Heartbeat到了 ...

  2. opengl版本

    OpenGL vendor string: IntelOpenGL renderer string: Intel(R) HD Graphics 630OpenGL version string: 4. ...

  3. initGanttView

    void TeslaManage::initGanttView() { if (vcGanttObject ==NULL) { vcGanttObject = new VCGantt(this); g ...

  4. osg::MatrixTransform 模型基本变换

    VCNodeMatrix.h #pragma once #include <osgViewer/Viewer> #include <osgViewer/ViewerEventHand ...

  5. spark实现wordcount

    spark-shell --master yarnsc:val lineRDD=sc.textFile("/test/input/test")lineRDD.collect().f ...

  6. laravel php门面模式

    门面模式   理解3个概念: 1)Container的概念,laravel所有的服务都注册在container里面,至于如何注册,就是使用service provider   2)service pr ...

  7. 偶尔在网上看到的,相对比较好的c#端订单号生成规则

    偶尔在网上看到的,相对比较好的c#端订单号生成规则 public class BillNumberBuilder{     private static object locker = new obj ...

  8. iOS-UIAlertView与UIActionSheet

    UIAlertView与UIActionSheet 6.11.1 常规调用 UIAlertView:调出一个模态对话框,屏幕居中显示 UIActionSheet:非模态对话框,屏幕下方弹出 Alert ...

  9. 安卓 adb命令

    获取包名 aapt d badging C:\Users\600844\Desktop\beijingtoon.apk "package launchable-activity" ...

  10. OpenCV直方图(直方图、直方图均衡,直方图匹配,原理、实现)

    1 直方图 灰度级范围为 \([0,L-1]\) 的数字图像的直方图是离散函数 \(h(r_k) = n_k\) , 其中 \(r_k\) 是第\(k\)级灰度值,\(n_k\) 是图像中灰度为 \( ...