使用Extended Events诊断SQL Server 2012----查看由Extended Event捕获的数据

这里来看看如何查看由Extended Events会话捕获的数据。如本章前面所述,可以用一些不同类型的目标。当你使用SSMS时,有不同方式来查看它们的内容。一开始你查看捕获的数据的最可能的方式是当它发生时。SSMS支持本地实时查看一些会话目标的数据,这意味着当事件发生时你就可以观察到正在收集的事件数据,就像你使用Profiler一样。然而,一旦会话停止,你还想回顾捕获的数据,或者在完全不同的服务器上。SSMS也支持这点,打开事件文件来查看,大致类似Word打开一个文档文件。最后,有一些目标,如环形缓冲区,SSMS不容易处理;相反,它会显示其所拥有的原始XML数据。要从该目标提取数据,需要T-SQL查询,然而同样的查询也能用于查询事件文件,因此你可以复用写好的查询。这节剩下的部分将说明如何查看存储在下面类型的Extended Event目标的数据:

  • 事件文件
  • 内存结构,如事件计数器和直方图
  • 基于XML的环形缓冲区

查看事件文件数据

使用事件文件作为你的会话目标是个不错的选择,因为考虑到灵活性,当你要查看其捕获的数据时,它是最佳的目标选项。使用SSMS,你可以查看正被捕获的实时内容,以及在会话停止后查看一个独立的数据文件。

查看实时数据

这个例子使用前面创建的会话,它捕获开启后的登录事件。在SSMS中右击会话,点击Watch Live Data选项,如图13-20所示。这会在SSMS中打开一个新的选项卡,它会提示“正在从服务器检索事件信息...”,然后你会看到捕获的事件。从另一个引起事件的PC连接到实例,如图13-21所示。

输出的屏幕分成两块,从截图中额可以识别。上面的框显示了捕获的所有事件的列表-----在这个例子中,是一些登录事件。下面的框显示了上框中所选中的事件所捕获的事件及全局栏位。然而,上面的框可以显示更多的信息,如果在捕获事件时你宁愿看到更多的栏位。你可以通过右击竖条(column bar)来定制视图,选择Choose Columns(如图13-22)。Choose Columns对话框就会出现(如图13-23)。

这会重新配置实时数据视图,来查看一些如图13-24所示的信息。

查看保存的数据

如果你已配置会话,使用事件文件作为它的目标,那么捕获的事件也会被写入磁盘。你可以在会话进行时、或停止后读取磁盘上事件文件的内容,还可以把文件从服务器复制到你的笔记本。要打开文件,在SSMS中选择File=>Open=>File,在这里你可以浏览任何地方的事件文件。默认情况下,它们在下面的路径:

C:\Program Files\Microsoft SQL Server\MSSQL11.x\MSSQL\Log

并且有一个默认的扩展名为.xel的文件。当实时数据显示时,打开其中有你看到的相同数据的文件。

使用T-SQL也可以打开事件文件。像SQL Trace,函数sys.fn_xe_file_target_read_file读取OS文件并返回基于XML的表数据。如果你想对Extended Events数据执行大量的分析,那么写查询来处理XML会成为你所擅长的;但是现在,下面的查询提供了一个例子,即如何读取事件文件来查看捕获的登录事件:

select event_data.value('(event/@timestamp)[1]', 'datetime2') as
[Event_Time_UTC],
event_data.value('(event/action[@name="nt_username"]/value)[1]',
'varchar(100)') as [NT_Username],
event_data.value('(event/action[@name="client_hostname"]/value)[1]',
'varchar(100)') as [Client_Hostname],
event_data.value('(event/action[@name="client_app_name"]/value)[1]',
'varchar(100)') as [Client_Appname]
from (select cast(event_data as xml)
from sys.fn_xe_file_target_read_file('C:\Program
Files\Microsoft SQL Server\MSSQL11.SQL2012\MSSQL\Log\
Logins_0_129805987593580000.xel', null, null, null)
) as results(event_data)
order by [Event_Time_UTC]

上述的查询会返回类似下面的结果:


Event_Time_UTC NT_Username Client_Hostname Client_Appname
--------------------------- ---------------- --------------- -------------------
2012-05-04 09:55:06.6850000 Gavin-VAIO\Gavin GAVIN-VAIO Microsoft SQL
Server Management
Studio
2012-05-04 09:55:06.7000000 Gavin-VAIO\Gavin GAVIN-VAIO Microsoft SQL
Server Management
Studio

 Extended Events使用的时间戳总是存储为UTC格式。你可能想使用dateadd或类似的函数来把时间戳格式化成你所在的时区。是否要这样做取决于为何要收集数据,以及本地时间信息是否重要。

查看In-Memory目标

一些目标是对捕获的数据执行计算的结果,而不是原始数据----例如,事件计数器。这些目标的结果仍然可以通过查看SSMS来获得,但是鉴于事件文件目标几乎是实时更新的,in-momory目标必须手动刷新或排计划刷新。这听起来不是个大问题,因为它们仍然可以几秒钟刷新一次,你需要事先配置好它。例如,前面重新配置的登录会话添加了一个事件计数器目标。你可以在SSMS里看到目标的列表,如图13-25所示。

一旦会话在运行,你就可以右击事件计数器目标并选择View Target Data。如图13-26所示,这将显示事件计数器的数据和一条消息“The target data will not be refreshed. Right click the table to manually refresh or set the automatic refresh interval.”。右击将显示,你可以让它每5秒钟及每小时之间的任意点进行自动刷新。

你可以用同查看事件计数器一样的方式查看直方图的结果;然而,由于有in-memory数据结构,一旦会话停止,它们的结果不会写入事件文件,或者存放在任何地方。这个地方或许更适合使用T-SQL分析事件文件。

使用T-SQL查询Ring Buffer

最后,这节整合前面你所看到的,使用T-SQL查看in-memory目标,环形缓存区。这样做最可能的原因是环形缓存区存储结果仅用XML格式因此,它们在进一步分析前必须转换成关系型数据。环形缓存区存放在一个叫sys.dm_xe_session_targets的DMV,你是从这里查询它们的内容。最后一个例子创建一个叫做Logins_rb的会话,来把数据写入一个环形缓存区目标。要创建这个,通过图13-27和13-28标注的选项来创建一个新的会话。

一旦开启会话,环形缓存区就开始有事件数据写入,使用DMV以有意义的格式提取内容是可能的,如下面的查询所示:

select events.value('(event/@timestamp)[1]', 'datetime2') as [Event_Time_UTC],
events.value('(event/action[@name="nt_username"]/value)[1]',
'varchar(100)') as [NT_Username],
events.value('(event/action[@name="client_hostname"]/value)[1]',
'varchar(100)') as [Client_Hostname],
events.value('(event/action[@name="client_app_name"]/value)[1]',
'varchar(100)') as [Client_Appname]
from (select event_data.query('.') as events
from
(select cast(target_data as xml) as target_data
from sys.dm_xe_session_targets xt
join sys.dm_xe_sessions xs
on xs.address = xt.event_session_address
where xs.name = 'Logins_rb'
and xt.target_name = 'ring_buffer' ) as data
cross apply target_data.nodes ('RingBufferTarget/event') as
results(event_data)) as tab (events)
order by [Event_Time_UTC]

查询返回的结果和前面查询其他目标一样,差异就是它们的源不再是物理文件。

如你从前面的查询所看到,现在你可以比新手处理复杂得多的Extended Events。然而,如果你有兴趣深入研究,那么我推荐阅读SQL Server社区专家Jonathan Kehayias写的关于Extended Events的博客。Jonathan不仅写了一些非常详细的有关Extended Events的文章,而且还有一些无价的脚本。实际上,前面额查询就是基于Jonathan的http://sqlskills.com/blogs/jonathan/category/Extended-Events.aspx


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将Excel数据插入SqlServer中并避免重复数据,可以使用以下步骤: 1. 将Excel数据读取到DataTable中。 2. 在DataTable中检查是否存在重复数据,如果存在则删除重复数据。 3. 使用SqlBulkCopy将数据插入到SqlServer中。 以下是示例代码: ```csharp using System.Data; using System.Data.OleDb; using System.Data.SqlClient; //连接Excel文件 string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\\sample.xlsx;Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\""; OleDbConnection excelConn = new OleDbConnection(connString); excelConn.Open(); //读取Excel数据到DataTable中 string sql = "SELECT * FROM [Sheet1$]"; OleDbDataAdapter adapter = new OleDbDataAdapter(sql, excelConn); DataTable excelData = new DataTable(); adapter.Fill(excelData); excelConn.Close(); //检查是否存在重复数据 for (int i = excelData.Rows.Count - 1; i >= 0; i--) { DataRow row = excelData.Rows[i]; if (IsDuplicate(row)) { excelData.Rows.Remove(row); } } //将数据插入到SqlServer中 string sqlServerConnString = "Data Source=.;Initial Catalog=TestDB;Integrated Security=True;"; SqlConnection sqlServerConn = new SqlConnection(sqlServerConnString); sqlServerConn.Open(); SqlTransaction tran = sqlServerConn.BeginTransaction(); try { using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlServerConn, SqlBulkCopyOptions.Default, tran)) { bulkCopy.DestinationTableName = "Person"; bulkCopy.ColumnMappings.Add("Name", "Name"); bulkCopy.ColumnMappings.Add("Age", "Age"); bulkCopy.WriteToServer(excelData); } tran.Commit(); } catch (Exception ex) { tran.Rollback(); throw ex; } finally { sqlServerConn.Close(); } //检查是否存在重复数据的方法 private bool IsDuplicate(DataRow row) { string name = row["Name"].ToString(); int age = int.Parse(row["Age"].ToString()); string sql = "SELECT COUNT(*) FROM Person WHERE Name=@Name AND Age=@Age"; using (SqlConnection conn = new SqlConnection(sqlServerConnString)) { SqlCommand cmd = new SqlCommand(sql, conn); cmd.Parameters.AddWithValue("@Name", name); cmd.Parameters.AddWithValue("@Age", age); conn.Open(); int count = (int)cmd.ExecuteScalar(); if (count > 0) { return true; } else { return false; } } } ``` 以上代码中使用了IsDuplicate方法来检查是否存在重复数据,该方法查询了目标表中是否存在相同的Name和Age值。如果存在则返回true,否则返回false。在使用SqlBulkCopy插入数据时,应该先将Excel数据读取到DataTable中,然后在DataTable中检查是否存在重复数据,最后再将数据插入到SqlServer中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值