如何在向用户传送记录的同时在后台保存 SQL 查询分析?
How to save SQL query analytics in the background while still delivering records to user?
我想知道是否有一种有效的方法来记录来自 SQL 查询的分析,同时仍向请求者提供记录?我目前使用的是 MS SQL Server 2012。
比方说,用户可以通过多种方式从数据库中提取记录(SSRS、SSIS、基于网页等),由于找不到更好的术语,我们就称它们为报告吧。随着时间的推移,很高兴知道哪些报告正在 运行,什么时候是 运行,报告到 运行 需要多长时间,返回的记录数是多少给定的报告等等。这些分析数据点可以让我关注事物——请求最多、最长 运行ning、最活跃的用户等。
现在我已经建立了一个系统,其中我有一个视图,它是报告的完整 "base records" 集,以及最终用户调用在视图上运行的存储过程——它调用查看并将过滤后的结果转储到 SProc 内的 @TempTable
中。 SProc除了根据User的需要过滤View返回的记录外,还会记录执行的时间、持续时间、记录数、提供的参数等,所有这些都保存到一个单独的"Analytics"table 进行单独分析。最后,SProc 只是 returns 从 @TempTable
到用户的记录。
虽然这确实有效,但感觉很笨重,并且确实会增加一两秒的总处理时间。我希望有一种更有效的方法来完成这种信息的背景捕获?
注意:第三方软件不适合我的环境。
我有一个要求,所有请求都必须在 1 秒以内。考虑到复杂性,这不是一项小任务。
无论如何,这是一个非常精简的版本。这里的关键是我将请求和参数存储为XML。您可以根据需要扩展或收缩列 and/or XML 部分。
看看 dbFiddle
日志Table结构
CREATE TABLE [dbo].[uniLog](
[LogNr] [int] IDENTITY(1,1) NOT NULL,
[LogUTC] [datetime] NULL,
[LogMS] [int] NULL,
[LogRows] [int] NULL,
[LogParam] [xml] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
一个虚拟存储过程
注意程序顶部的 @TimeBeg
和 END
之后的 INSERT
CREATE PROCEDURE [dbo].[prcDummyProcedure] (
@SomeStr varchar(50),
@SomeInt int,
@AnotherInt int,
@FromDate date
)
As
Begin
Set NoCount On
Declare @TimeBeg datetime = getutcdate()
-- My Super Awsome Query
Select Top 5000 *,N=Row_Number() Over (Order By (Select NULL)) From master..spt_values n1, master..spt_values n2
Declare @Rows int = @@RowCount
End
Insert Into [dbo].[uniLog] (LogUTC,LogMS,LogRows,LogParam)
values ( GetUTCDate()
,DateDiff(MILLISECOND,@TimeBeg,getutcdate())
,@Rows
,(Select ProcName = '[dbo].[prcDummyProcedure]'
,SomeStr = @SomeStr
,SomeInt = @SomeInt
,AnotherInt = @AnotherInt
,FromDate = @FromDate
For XML Raw )
)
现在测试
Exec [dbo].[prcDummyProcedure] 'SomeString',100,200,'2020-01-31'
Select * from [dbo].[uniLog]
结果
[结果将是 SP 的设计目的]
日志 table 更新为
LogNr LogUTC LogMS LogRows LogParam
6 2020-03-10 19:55:35.423 13 1000 <row ProcName="[dbo].[prcDummyProcedure]" SomeStr="SomeString" SomeInt="100" AnotherInt="200" FromDate="2020-01-31" />
我想知道是否有一种有效的方法来记录来自 SQL 查询的分析,同时仍向请求者提供记录?我目前使用的是 MS SQL Server 2012。
比方说,用户可以通过多种方式从数据库中提取记录(SSRS、SSIS、基于网页等),由于找不到更好的术语,我们就称它们为报告吧。随着时间的推移,很高兴知道哪些报告正在 运行,什么时候是 运行,报告到 运行 需要多长时间,返回的记录数是多少给定的报告等等。这些分析数据点可以让我关注事物——请求最多、最长 运行ning、最活跃的用户等。
现在我已经建立了一个系统,其中我有一个视图,它是报告的完整 "base records" 集,以及最终用户调用在视图上运行的存储过程——它调用查看并将过滤后的结果转储到 SProc 内的 @TempTable
中。 SProc除了根据User的需要过滤View返回的记录外,还会记录执行的时间、持续时间、记录数、提供的参数等,所有这些都保存到一个单独的"Analytics"table 进行单独分析。最后,SProc 只是 returns 从 @TempTable
到用户的记录。
虽然这确实有效,但感觉很笨重,并且确实会增加一两秒的总处理时间。我希望有一种更有效的方法来完成这种信息的背景捕获?
注意:第三方软件不适合我的环境。
我有一个要求,所有请求都必须在 1 秒以内。考虑到复杂性,这不是一项小任务。
无论如何,这是一个非常精简的版本。这里的关键是我将请求和参数存储为XML。您可以根据需要扩展或收缩列 and/or XML 部分。
看看 dbFiddle
日志Table结构
CREATE TABLE [dbo].[uniLog](
[LogNr] [int] IDENTITY(1,1) NOT NULL,
[LogUTC] [datetime] NULL,
[LogMS] [int] NULL,
[LogRows] [int] NULL,
[LogParam] [xml] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
一个虚拟存储过程
注意程序顶部的 @TimeBeg
和 END
INSERT
CREATE PROCEDURE [dbo].[prcDummyProcedure] (
@SomeStr varchar(50),
@SomeInt int,
@AnotherInt int,
@FromDate date
)
As
Begin
Set NoCount On
Declare @TimeBeg datetime = getutcdate()
-- My Super Awsome Query
Select Top 5000 *,N=Row_Number() Over (Order By (Select NULL)) From master..spt_values n1, master..spt_values n2
Declare @Rows int = @@RowCount
End
Insert Into [dbo].[uniLog] (LogUTC,LogMS,LogRows,LogParam)
values ( GetUTCDate()
,DateDiff(MILLISECOND,@TimeBeg,getutcdate())
,@Rows
,(Select ProcName = '[dbo].[prcDummyProcedure]'
,SomeStr = @SomeStr
,SomeInt = @SomeInt
,AnotherInt = @AnotherInt
,FromDate = @FromDate
For XML Raw )
)
现在测试
Exec [dbo].[prcDummyProcedure] 'SomeString',100,200,'2020-01-31'
Select * from [dbo].[uniLog]
结果
[结果将是 SP 的设计目的]
日志 table 更新为
LogNr LogUTC LogMS LogRows LogParam
6 2020-03-10 19:55:35.423 13 1000 <row ProcName="[dbo].[prcDummyProcedure]" SomeStr="SomeString" SomeInt="100" AnotherInt="200" FromDate="2020-01-31" />