我正在编写一个查询来模拟Sql Server Profiler,我的版本是Sql Server 2008我没有Sql Profiler而且我需要它,此时我得到了这个查询:
Use master
Go
Alter procedure dbo.NS_sp_profilerQuery
@dbName sysname='',
@userName sysname=Null,
@hostName sysname=Null
As
Begin
--Step 1. Declaration of variables.
Declare @idDb Int=DB_ID(@dbName);
Declare @Query Nvarchar(Max);
--Step 2. SETTING THE query.
Select @Query = N'Select '+
N'idProceso=syp.spid,basedatos=DB_NAME(syp.dbid),usuario=syp.loginame,cpu,hostname,espera=lastwaittype,[bloqueadoPor]=blocked,Query=(Select text from ::fn_get_sql(syp.sql_handle)) '+
N'From master.dbo.sysprocesses syp '+
N'Where 1=1 '+
(case when @idDb is null then '' else 'and syp.dbid='+Ltrim(Rtrim(Str(@idDb))) end)+
(case when @userName is null then '' else ' and Ltrim(Rtrim(syp.loginame))='+Quotename(Ltrim(Rtrim(@userName)),Char(39)) end)+
(case when @hostName is null then '' else ' and Ltrim(Rtrim(syp.hostname))='+Quotename(Ltrim(Rtrim(@hostName)),Char(39)) end);
--Step 3. Query and return data.
Exec(@Query);
End
Go
此查询在一个点上捕获所有内容,我的问题是: 捕获长时间发生的所有事情的最佳方法是什么?,制作循环? 你会建议什么?
答案 0 :(得分:2)
使用单个查询来模拟探查器是不可能的。您将获得当前正在运行的查询的快照。如果您想查看需要很长时间才能运行的查询,这对您来说可能已经足够了,但在这种情况下,我宁愿建议您查看dmv sys.dm_exec_query_stats。通过这个,您可以检查哪些查询占用了大量资源或时间。
示例,包括查询计划:
-- List top 100 queries that has the highest average logical reads
select top (100) *
from sys.dm_exec_query_stats qs
cross apply sys.dm_exec_query_plan(qs.plan_handle) p
order by cast(qs.total_logical_reads as float) / qs.execution_count desc;
有许多有趣的列可供选择。
如果您真的想要捕获所有已执行的查询,您应该查看扩展事件。您可以记录所需的查询,例如稍后可以检查的文件或环形缓冲区。设置它需要做一些工作,但官方的sql server文档提供了有关如何操作的很好的信息。
答案 1 :(得分:0)
此查询解决了我的需求,它可以工作99%,我将快照发送到dbo.sysprocesses。
Use master
Go
Alter procedure dbo.NS_sp_profilerQuery
@dbName sysname='',
@userName sysname=Null,
@hostName sysname=Null,
@Seconds int
As
Begin
Declare @SnapShots Table(
idProceso int,
idThread int,
basedatos sysname,
usuario sysname,
cpu int,
hostname sysname,
espera sysname,
bloqueadoPor int,
Query Nvarchar(Max)
);
Declare @Profiler Table(
idProceso int,
idThread int,
basedatos sysname,
usuario sysname,
cpu int,
hostname sysname,
espera sysname,
bloqueadoPor int,
Query Nvarchar(Max)
);
--Paso 1. Declaración de variables.
Declare @idDb Int=DB_ID(@dbName);
Declare @Query Nvarchar(Max);
Declare @HoraFinal Datetime=DateAdd(Second,@Seconds,Getdate());
While Getdate()<=@HoraFinal
Begin
--Paso 2. Seteo de consulta.
Select @Query = N'Select '+
N'idProceso=syp.spid,idThread=syp.kpid,basedatos=DB_NAME(syp.dbid),usuario=syp.loginame,cpu,hostname,espera=lastwaittype,[bloqueadoPor]=blocked,Query=(Select text from ::fn_get_sql(syp.sql_handle)) '+
N'From master.dbo.sysprocesses syp '+
N'Where 1=1 '+
(case when @idDb is null then '' else 'and syp.dbid='+Ltrim(Rtrim(Str(@idDb))) end)+
(case when @userName is null then '' else ' and Ltrim(Rtrim(syp.loginame))='+Quotename(Ltrim(Rtrim(@userName)),Char(39)) end)+
(case when @hostName is null then '' else ' and Ltrim(Rtrim(syp.hostname))='+Quotename(Ltrim(Rtrim(@hostName)),Char(39)) end);
--Paso 3. Consulta y retorno de datos.
Insert Into @SnapShots(idProceso,idThread,basedatos,usuario,cpu,hostname,espera,bloqueadoPor,Query)
Exec(@Query);
Insert Into @Profiler(idProceso,idThread,basedatos,usuario,cpu,hostname,espera,bloqueadoPor,Query)
Select
sna.idProceso,sna.idThread,sna.basedatos,sna.usuario,sna.cpu,sna.hostname,sna.espera,sna.bloqueadoPor,sna.Query
From @SnapShots sna
Left Join @Profiler pro
On (sna.idProceso=pro.idProceso and sna.idThread=pro.idThread)
Where pro.idProceso is null;
Delete From @SnapShots;
End
Select
idProceso,idThread,basedatos,usuario,cpu,hostname,espera,bloqueadoPor,Query
From @Profiler;
End
Go