您的位置:首页 > 数据库

SQL Server基线算法(同比和环比)

2014-12-17 22:05 162 查看

基线介绍

基线为历史数据统计而成的数据,具有参考价值,并利用基线数据与当前值的对比,通过一定的报警机制,形成实时监控架构。SQL Server计数器采用同比和环比两种方式。

/****************************** 功能描述:<环比基线算法>
*   创建者:<HuangCH〉
*   创建日期:<2014-11-05>
*   备注说明:<每小时执行一次>
##########
Change Log
##########
Date                 Changer             Description
--------------------------------------------------
<2014-11-05>        <HuangCH>            <新建>
说明:
1、环比算法可以统计一天后的数据

2、如果开始时间与当前时间对比超过一天,则只取开始时间当天的数据进行计算--CONVERT(VARCHAR(26),DATEADD(D,1,@LastRBaseEnd),23)< = @LastOneMinute

3、如果时间分别为两天的0点,则需要单独处理当天0点的数据--DATEDIFF(MI,@RunRBaseStart,@RunRBaseEnd)=1440

4、环比算法,分离工作日和周末,本别计算,统计两周内的数据--DATEPART(WEEKDAY,@RunRBaseStart) IN(2,3,4,5,6)--非周末

--------------------------------------------------
***************************/
ALTER PROC [dbo].[spb_RBaseCounterData]
AS
SET NOCOUNT ON
SET DATEFIRST 7--由于需要考虑工作日与周末,因此需要确认默认设置是以周日开始
DECLARE @LastOneMinute DATETIME
DECLARE @LastRBaseEnd DATETIME --计算一周之后的数据
DECLARE @RunRBaseEnd DATETIME
DECLARE @RunRBaseStart DATETIME
DECLARE @SqlCmd   VARCHAR(MAX)
DECLARE @WHERE VARCHAR(2000)
DECLARE @GROUPBY VARCHAR(MAX)
DECLARE @CYLE INT
DECLARE @MachineName VARCHAR(128)
DECLARE @ERRORMSG VARCHAR(MAX)
SET @ERRORMSG=''

--更新未超过一周的数据
UPDATE SQLPerfDataStat.dbo.CounterDetails_Dts
SET LastRBaseEnd=CONVERT(DATETIME,CONVERT(VARCHAR(16),GETDATE(),120))
WHERE DATEADD(WEEK,-1,LastOneMinute)<CreateTime

--取最后计算小于当前统计时间的数据
DECLARE RBaseCur CURSOR FOR
SELECT MachineName,LastOneMinute,CONVERT(DATETIME,CONVERT(VARCHAR(16),LastRBaseEnd,120))  LastRBaseEnd
FROM SQLPerfDataStat.dbo.CounterDetails_Dts WITH(NOLOCK)
WHERE  DATEDIFF(MI,LastRBaseEnd,LastOneMinute)>1  AND DATEADD(WEEK,-1,LastOneMinute)>=CreateTime--不超过新建时间一周,则不处理

OPEN RBaseCur

FETCH NEXT FROM RBaseCur INTO @MachineName,@LastOneMinute,@LastRBaseEnd

WHILE @@FETCH_STATUS=0
BEGIN

IF CONVERT(VARCHAR(26),DATEADD(D,1,@LastRBaseEnd),23)< = @LastOneMinute--如果第二天0点小于当前时间;即不能跨天处理
BEGIN
SET  @RunRBaseEnd=CONVERT(VARCHAR(26),DATEADD(D,1,@LastRBaseEnd),23)
SET  @RunRBaseStart=@LastRBaseEnd
END
ELSE
BEGIN--在同一天
SET  @RunRBaseEnd=@LastOneMinute
SET  @RunRBaseStart=@LastRBaseEnd
END

IF DATEPART(WEEKDAY,@RunRBaseStart) IN(2,3,4,5,6)--非周末
BEGIN
SET @WHERE='WHERE ((CounterDateTime>'+CASE WHEN CONVERT(VARCHAR(24),@RunRBaseStart,120)=CONVERT(VARCHAR(24),@RunRBaseStart,23)+' 00:00:00' THEN ''ELSE '=' END +''''+CONVERT(VARCHAR(24),@RunRBaseStart,120)+''' AND CounterDateTime<'''+CONVERT(VARCHAR(24),@RunRBaseEnd,120)+''')'
SET @CYLE =1
WHILE(@CYLE<14)
BEGIN
IF DATEPART(WEEKDAY,DATEADD(D,-@CYLE,@RunRBaseStart)) IN(2,3,4,5,6)
BEGIN
SET @WHERE=@WHERE+CHAR(10)+'OR (CounterDateTime>'++CASE WHEN CONVERT(VARCHAR(24),@RunRBaseStart,120)=CONVERT(VARCHAR(24),@RunRBaseStart,23)+' 00:00:00' THEN ''ELSE '=' END ++''''+CONVERT(VARCHAR(24),DATEADD(D,-@CYLE,@RunRBaseStart),120)+''' AND CounterDateTime<'''+CONVERT(VARCHAR(24),DATEADD(D,-@CYLE,@RunRBaseEnd),120)+''')'
END
SET @CYLE = @CYLE + 1
END
SET @GROUPBY='DATEADD(MI,-DATEDIFF(MI,CounterDateTime,'''+CONVERT(VARCHAR(24),@RunRBaseEnd,120)+''')%(24*60),'''+CASE WHEN DATEPART(WEEKDAY,@RunRBaseStart) =6 THEN CONVERT(VARCHAR(24),DATEADD(D,3,@RunRBaseEnd),120) ELSE CONVERT(VARCHAR(24),DATEADD(D,1,@RunRBaseEnd),120) END+''')'--周五要计算周一的数据
END
ELSE--周末数据,取近两周周末数据库
BEGIN
SET @WHERE='WHERE ((CounterDateTime>'+CASE WHEN CONVERT(VARCHAR(24),@RunRBaseStart,120)=CONVERT(VARCHAR(24),@RunRBaseStart,23)+' 00:00:00' THEN ''ELSE '=' END +''''+CONVERT(VARCHAR(24),@RunRBaseStart,120)+''' AND CounterDateTime<'''+CONVERT(VARCHAR(24),@RunRBaseEnd,120) +''')'
+CHAR(10)+'OR (CounterDateTime>'+CASE WHEN CONVERT(VARCHAR(24),@RunRBaseStart,120)=CONVERT(VARCHAR(24),@RunRBaseStart,23)+' 00:00:00' THEN ''ELSE '=' END +''''+CONVERT(VARCHAR(24),DATEADD(WEEK,-1,@RunRBaseStart),120)+''' AND CounterDateTime<'''+CONVERT(VARCHAR(24),DATEADD(WEEK,-1,@RunRBaseEnd),120)+''')'
SET @GROUPBY='DATEADD(MI,-DATEDIFF(MI,CounterDateTime,'''+CONVERT(VARCHAR(24),@RunRBaseEnd,120)+''')%(24*60),'''+CONVERT(VARCHAR(24),DATEADD(WEEK,1,@RunRBaseEnd),120)+''')'
END

UPDATE SQLPerfDataStat.dbo.CounterDetails_Dts
SET LastRBaseEnd=@RunRBaseEnd
WHERE MachineName=@MachineName

BEGIN TRY
--插入数据
SET @SqlCmd='INSERT INTO dbo.RBaseCounterData_OneMinute(CounterID, CounterDateTime, CounterValue,MaxCounterValue)'
+CHAR(10)+'SELECT CounterID,'+@GROUPBY+',AVG(CounterValue),MAX(CounterValue) FROM'
+CHAR(10)+'(SELECT CounterID,CounterDateTime,CounterValue'
+CHAR(10)+'FROM CounterData_OneMinute a (NOLOCK)'
+CHAR(10)+@WHERE+') '
+CHAR(10)+'AND EXISTS (SELECT TOP 1 1 FROM CounterDetails_Collect WITH(NOLOCK) WHERE CounterID = a.CounterID AND MachineName='''+@MachineName+''')'
+CHAR(10)+'Union all'
+CHAR(10)+'SELECT CounterID,CounterDateTime,CounterValue'
+CHAR(10)+'FROM SQLPerfDataStat_Histroy.dbo.CounterData_OneMinute_bak a (NOLOCK)'
+CHAR(10)+@WHERE+') '
+CHAR(10)+'AND EXISTS (SELECT TOP 1 1 FROM CounterDetails_Collect WITH(NOLOCK) WHERE CounterID = a.CounterID AND MachineName='''+@MachineName+''')'
+CHAR(10)+')AA'
+CHAR(10)+ 'GROUP BY CounterID,'+@GROUPBY
exec (@SqlCmd)

--0点数据处理
IF CONVERT(VARCHAR(24),@RunRBaseStart,120)=CONVERT(VARCHAR(24),@RunRBaseStart,23)+' 00:00:00'
BEGIN
IF DATEPART(WEEKDAY,@RunRBaseStart) IN(2,3,4,5,6)--非周末
BEGIN
SET @WHERE='WHERE ((CounterDateTime='''+CONVERT(VARCHAR(24),@RunRBaseStart,120)+''')'
SET @CYLE =1
WHILE(@CYLE<14)
BEGIN
IF DATEPART(WEEKDAY,DATEADD(D,-@CYLE,@RunRBaseStart)) IN(2,3,4,5,6)
BEGIN
SET @WHERE=@WHERE+CHAR(10)+'OR (CounterDateTime='''+CONVERT(VARCHAR(24),DATEADD(D,-@CYLE,@RunRBaseStart),120)+''')'
END
SET @CYLE = @CYLE + 1
END
SET @GROUPBY='DATEADD(MI,-DATEDIFF(MI,CounterDateTime,'''+CONVERT(VARCHAR(24),@RunRBaseEnd,120)+''')%(24*60),'''+CASE WHEN DATEPART(WEEKDAY,@RunRBaseStart) =6 THEN CONVERT(VARCHAR(24),DATEADD(D,3,@RunRBaseEnd),120) ELSE CONVERT(VARCHAR(24),DATEADD(D,1,@RunRBaseEnd),120) END+''')'
END
ELSE--周末数据,取近两周周末数据库
BEGIN
SET @WHERE='WHERE ((CounterDateTime='''+CONVERT(VARCHAR(24),@RunRBaseStart,120)+''')'
+CHAR(10)+'OR (CounterDateTime='''+CONVERT(VARCHAR(24),DATEADD(WEEK,-1,@RunRBaseStart),120)+''')'
SET @GROUPBY='DATEADD(MI,-DATEDIFF(MI,CounterDateTime,'''+CONVERT(VARCHAR(24),@RunRBaseEnd,120)+''')%(24*60),'''+CONVERT(VARCHAR(24),DATEADD(D,-1,DATEADD(WEEK,1,@RunRBaseEnd)),120)+''')'
END
SET @SqlCmd='INSERT INTO dbo.RBaseCounterData_OneMinute(CounterID, CounterDateTime, CounterValue,MaxCounterValue)'
+CHAR(10)+'SELECT CounterID,'+@GROUPBY+',AVG(CounterValue),MAX(CounterValue) FROM'
+CHAR(10)+'(SELECT CounterID,CounterDateTime,CounterValue'
+CHAR(10)+'FROM CounterData_OneMinute a (NOLOCK)'
+CHAR(10)+@WHERE+') '
+CHAR(10)+'AND EXISTS (SELECT TOP 1 1 FROM CounterDetails_Collect WITH(NOLOCK) WHERE CounterID = a.CounterID AND MachineName='''+@MachineName+''')'
+CHAR(10)+'Union all'
+CHAR(10)+'SELECT CounterID,CounterDateTime,CounterValue'
+CHAR(10)+'FROM SQLPerfDataStat_Histroy.dbo.CounterData_OneMinute_bak a (NOLOCK)'
+CHAR(10)+@WHERE+') '
+CHAR(10)+'AND EXISTS (SELECT TOP 1 1 FROM CounterDetails_Collect WITH(NOLOCK) WHERE CounterID = a.CounterID AND MachineName='''+@MachineName+''')'
+CHAR(10)+')AA'
+CHAR(10)+ 'GROUP BY CounterID,'+@GROUPBY
exec (@SqlCmd)
END

END TRY
BEGIN CATCH
SET @ERRORMSG=@ERRORMSG+ERROR_MESSAGE()
IF @@TRANCOUNT >0
BEGIN
ROLLBACK;
END
END CATCH

FETCH NEXT FROM RBaseCur INTO @MachineName,@LastOneMinute,@LastRBaseEnd
END
CLOSE RBaseCur
DEALLOCATE  RBaseCur

IF @ERRORMSG<>''
BEGIN
;THROW 50000,@ERRORMSG,1
END


spb_RBaseCounterData
环比数据可以说明数据近期走势。具有优化对比价值。从上同比图可以看出117-27-139-238服务器cpu在历史上存在异常升高,下图红线环比比数据,却与蓝线同步,说明此异常在近期已经正常。



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: