<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      開源項目:高級SQL Server監控、性能圖、分析與優化、版本控制

      2011-12-05 09:48  靈感之源  閱讀(12250)  評論(60)    收藏  舉報

      這是一個相當高級的SQL Server監控工具,全面監控SQL Server的活動與性能,分析性能瓶頸,給出優化建議。

       

      red-gate有一個在線的數據庫監控工具,不過那個商業的東西價錢不便宜。我寫的這個平民版,開源,功能上有頗多的差異(各有長短)。

       

      項目在Codeplex上開源:http://sqlmon.codeplex.com/

       

      在Codeproject上有英文介紹:http://www.codeproject.com/KB/database/sqlmonitor.aspx

       

      介紹

      是否想過:“SQL Server為什么那么慢?”,“為什么CPU占用那么高?”,“到底哪里死鎖了?”,“為什么數據庫那么大?”,“怎樣才可以查看我的存儲過程和函數的歷史版本?”,“可以讓我的SQL Server跑得更快嗎?”。

       

      你的答案就在這里;-)

       

      到底能干嘛

      • 監控SQL Server的活動:進程、任務,詳細查看當前執行的語句與實際變量值,終止進程
      • IO/CPU/網絡等性能趨勢圖
      • 函數/存儲過程等的版本控制,這在商業軟件中也沒有(如果你知道,告訴我)
      • 對象瀏覽器:服務器、數據庫、表、視圖、函數、存儲過程等
      • 數據庫管理:收縮、日志清除、備份、恢復等
      • 在整個數據庫中搜索對象/腳本內容,這在SQL Server 2012中也無法做到
      • 自動顯示所有對象的腳本,如表、視圖、函數、存儲過程等

       

      概覽

       

       

      在上圖中,我們可以看見表的create腳本。如果你選擇其它對象,如函數、存儲過程等,一樣會顯示相應的腳本。

       

      在對象列表中,如果是數據表,顯示表的占用空間(包括索引)、記錄數等。

       

      這些在SQL Server 2012中都沒有。

       

      獲取數據庫信息

       

       

      View Code
      SELECT DB_NAME(database_id) AS DatabaseName, Name AS Logical_Name, Physical_Name, CAST(size AS decimal(30,0))*8 AS Size, state FROM sys.master_files WHERE DB_NAME(database_id) = 'YOUR_DATABASE_NAME' 

       

      對象/腳本搜索

       

       

      View Code
      --search in script
      Select s.name, s.create_date AS CreateDate, s.modify_date AS ModifyDate, s.type, c.text from syscomments c left join sys.objects s on c.id = s.object_id where [Text] like '%YOUR_QUERY_HERE%'

      --search in jobs
      SELECT job_id, name, date_created AS CreateDate, date_modified AS ModifyDate, 'Job' AS type FROM msdb.dbo.sysjobs

       

       

      獲取表結構

       

       

      --To get table names and records
      SELECT 
          [TableName] = so.name, 
          [RowCount] = MAX(si.rows) 
      FROM 
          sysobjects so, 
          sysindexes si 
      WHERE 
          so.xtype = 'U' 
          AND 
          si.id = OBJECT_ID(so.name) 
      GROUP BY 
          so.name
      --To get table used space
      EXEC sp_spaceused 'TABLE_NAME'
      --To get table script
      declare @Id int@i int@i2 int,@Sql varchar(max),@Sql2 varchar(max), @f1 varchar(5), @f2 varchar(5), @f3 varchar(5), @f4 varchar(5), @T varchar(5)
          select @Id=object_id('YOUR_TABLE_NAME_HERE'), @f1 = char(13+ char(10), @f2 = '    '@f3=@f1+@f2@f4=',' + @f3
          
          if not(@Id is null)
          BEGIN
          declare @Data table(Id int identity primary key, D varchar(maxnot null, ic int null, re int null, o int not null);
          
          -- Columns
          with c as(
              select c.column_id, Nr = row_number() over(order by c.column_id), Clr=count(*over(),
                  D = quotename(c.name) + ' ' +
                      case when s.name = 'sys' or c.is_computed=1 then '' else quotename(s.name) + '.' end +
                      case when c.is_computed=1 then '' when s.name = 'sys' then t.Name else quotename(t.name) end +
                      case when c.user_type_id!=c.system_type_id or c.is_computed=1 then ''
                          when t.Name in ('xml''uniqueidentifier''tinyint''timestamp''time''text''sysname''sql_variant''smallmoney''smallint''smalldatetime''ntext''money',
                                          'int''image''hierarchyid''geometry''geography''float''datetimeoffset''datetime2''datetime''date''bigint''bit'then ''
                          when t.Name in('varchar','varbinary''real''numeric''decimal''char''binary')
                              then '(' + isnull(convert(varchar,nullif(c.max_length,-1)), 'max'+ isnull(','+convert(varchar,nullif(c.scale, 0)), ''+ ')'
                          when t.Name in('nvarchar','nchar')
                              then '(' + isnull(convert(varchar,nullif(c.max_length,-1/ 2), 'max'+ isnull(','+convert(varchar,nullif(c.scale, 0)), ''+ ')'
                          else '??'
                          end + 
                      case when ic.object_id is not null then ' identity(' + convert(varchar,ic.seed_value) + ',' + convert(varchar,ic.increment_value) + ')' else '' end +
                      case when c.is_computed=1 then 'as' + cc.definition when c.is_nullable = 1 then ' null' else ' not null' end +
                      case c.is_rowguidcol when 1 then ' rowguidcol' else '' end +
                      case when d.object_id is not null then ' default ' + d.definition else  '' end
              from sys.columns c
              inner join sys.types t
              on t.user_type_id = c.user_type_id
              inner join sys.schemas s
              on s.schema_id=t.schema_id
              left outer join sys.computed_columns cc
              on cc.object_id=c.object_id and cc.column_id=c.column_id
              left outer join sys.default_constraints d
              on d.parent_object_id=@id and d.parent_column_id=c.column_id
              left outer join sys.identity_columns ic
              on ic.object_id=c.object_id and ic.column_id=c.column_id
              where c.object_id=@Id
              
          )
              insert into @Data(D, o)
              select '    ' + D + case Nr when Clr then '' else ',' + @f1 end0
              from c where NOT D IS NULL 
              order by column_id
          
          -- SubObjects
          set @i=0
          while 1=1
              begin
              select top 1 @i=c.object_id@T = c.type, @i2=i.index_id
              from sys.objects c 
              left outer join sys.indexes i
              on i.object_id=@Id and i.name=c.name
              where parent_object_id=@Id and c.object_id>@i and c.type not in('D')
              order by c.object_id
              if @@rowcount=0 break
              if @T = 'C' 
                  insert into @Data 
                  select @f4 + 'check ' + case is_not_for_replication when 1 then 'not for replication ' else '' end + definition, nullnull10
                  from sys.check_constraints where object_id=@i
              else if @T = 'Pk'
                  insert into @Data 
                  select @f4 + 'primary key' + isnull(' ' + nullif(lower(i.type_desc),'clustered'), ''), @i2null20
                  from sys.indexes i
                  where i.object_id=@Id and i.index_id=@i2
              else if @T = 'uq'
                  insert into @Data values(@f4 + 'unique'@i2null30)
              else if @T = 'f'
                  begin
                  insert into @Data 
                  select @f4 + 'foreign key'-1@i40
                  from sys.foreign_keys f
                  where f.object_id=@i
                  
                  insert into @Data 
                  select ' references ' + quotename(s.name) + '.' + quotename(o.name), -2@i41
                  from sys.foreign_keys f
                  inner join sys.objects o
                  on o.object_id=f.referenced_object_id
                  inner join sys.schemas s
                  on s.schema_id=o.schema_id
                  where f.object_id=@i
                  
                  insert into @Data 
                  select ' not for replication'-3@i42
                  from sys.foreign_keys f
                  inner join sys.objects o
                  on o.object_id=f.referenced_object_id
                  inner join sys.schemas s
                  on s.schema_id=o.schema_id
                  where f.object_id=@i and f.is_not_for_replication=1
                  end
              else
                  insert into @Data values(@f4 + 'Unknow SubObject [' + @T + ']'nullnull99)
              end

          insert into @Data values(@f1+')'nullnull100)
          
          -- Indexes
          insert into @Data
          select @f1 + 'create ' + case is_unique when 1 then 'unique ' else '' end + lower(s.type_desc) + ' index ' + 'i' + convert(varchar, row_number() over(order by index_id)) + ' on ' + quotename(sc.Name) + '.' + quotename(o.name), index_id, null1000
          from sys.indexes s
          inner join sys.objects o
          on o.object_id=s.object_id
          inner join sys.schemas sc
          on sc.schema_id=o.schema_id
          where s.object_id=@Id and is_unique_constraint=0 and is_primary_key=0 and s.type_desc != 'heap'
          
          -- columns
          set @i=0
          while 1=1
              begin
              select top 1 @i=ic from @Data where ic>@i order by ic 
              if @@rowcount=0 break
              select @i2=0@Sql=null@Sql2=null
              while 1=1
                  begin
                  select @i2=index_column_id, 
                      @Sql = case c.is_included_column when 1 then @Sql else isnull(@Sql + '''('+ cc.Name + case c.is_descending_key when 1  then ' desc' else '' end end,
                      @Sql2 = case c.is_included_column when 0 then @Sql2 else isnull(@Sql2 + '''('+ cc.Name + case c.is_descending_key when 1  then ' desc' else '' end end
                  from sys.index_columns c
                  inner join sys.columns cc
                  on c.column_id=cc.column_id and cc.object_id=c.object_id
                  where c.object_id=@Id and index_id=@i and index_column_id>@i2
                  order by index_column_id
                  if @@rowcount=0 break
                  end
              update @Data set D=D+@Sql +')' + isnull(' include' + @Sql2 + ')'''where ic=@i
              end
              
          -- references
          set @i=0
          while 1=1
              begin
              select top 1 @i=re from @Data where re>@i order by re
              if @@rowcount=0 break
              
              select @i2=0@Sql=null@Sql2=null
              while 1=1
                  begin
                  select @i2=f.constraint_column_id, 
                      @Sql = isnull(@Sql + '''('+ c1.Name,
                      @Sql2 = isnull(@Sql2 + '''('+ c2.Name
                  from sys.foreign_key_columns f
                  inner join sys.columns c1
                  on c1.column_id=f.parent_column_id and c1.object_id=f.parent_object_id
                  inner join sys.columns c2
                  on c2.column_id=f.referenced_column_id and c2.object_id=f.referenced_object_id
                  where f.constraint_object_id=@i and f.constraint_column_id>@i2
                  order by f.constraint_column_id
                  if @@rowcount=0 break
                  end
              update @Data set D = D + @Sql + ')'  where re=@i and ic=-1
              update @Data set D = D + @Sql2 + ')'  where re=@i and ic=-2
              end;
          
          -- Render
          with x as(
              select id=d.id-1, D=d.D + isnull(d2.D,'')
              from @Data d
              left outer join @Data d2
              on d.re=d2.re and d2.o=42
              where d.o=41
              
          )
          update @Data
              set D=d.D+x.D
          from @Data d
          inner join x
          on x.id=d.id
          
          delete @Data where o in(4142)
          
          select @Sql = 'create table ' + quotename(s.name) + '.' + quotename(o.name) + '(' + @f1
          from sys.objects o
          inner join sys.schemas s
          on o.schema_id = s.schema_id
          where o.object_id=@Id
          
          set @i=0
          while 1=1
              begin
              select top 1 @I=Id, @Sql = @Sql + D from @Data order by o, case when o=0 then right('0000' + convert(varchar,id),5)  else D end, id
              if @@rowcount=0 break
              delete @Data where id=@i
              end
          END
          SELECT @Sql

       

       

      性能趨勢圖

       

       

      在上圖中,我們可以看見SQL Server歷史/當前的IO/CPU/網絡信息都在趨勢圖中顯示。

       

      這些數據來自幾個系統變量:

       

      • @@cpu_busy
      • @@io_busy
      • @@idle
      • @@pack_received
      • @@pack_sent
      • @@connections
      • @@packet_errors
      • @@total_read
      • @@total_write
      • @@total_errors

       

       以下是相應的SQL:

       

      declare @now         datetime
      declare @cpu_busy     int
      declare @io_busy    int
      declare @idle        int
      declare @pack_received    int
      declare @pack_sent    int
      declare @pack_errors    int
      declare @connections    int
      declare @total_read    int
      declare @total_write    int
      declare @total_errors    int

      declare @oldcpu_busy     int    /* used to see if DataServer has been rebooted */
      declare @interval    int
      declare @mspertick    int    /* milliseconds per tick */


      /*
      **  Set @mspertick.  This is just used to make the numbers easier to handle
      **  and avoid overflow.
      */
      select @mspertick = convert(int@@timeticks / 1000.0)

      /*
      **  Get current monitor values.
      */
      select
          @now = getdate(),
          @cpu_busy = @@cpu_busy,
          @io_busy = @@io_busy,
          @idle = @@idle,
          @pack_received = @@pack_received,
          @pack_sent = @@pack_sent,
          @connections = @@connections,
          @pack_errors = @@packet_errors,
          @total_read = @@total_read,
          @total_write = @@total_write,
          @total_errors = @@total_errors

      /*
      **  Check to see if DataServer has been rebooted.  If it has then the
      **  value of @@cpu_busy will be less than the value of spt_monitor.cpu_busy.
      **  If it has update spt_monitor.
      */
      select @oldcpu_busy = cpu_busy
          from master.dbo.spt_monitor
      if @oldcpu_busy > @cpu_busy
      begin
          update master.dbo.spt_monitor
              set
                  lastrun = @now,
                  cpu_busy = @cpu_busy,
                  io_busy = @io_busy,
                  idle = @idle,
                  pack_received = @pack_received,
                  pack_sent = @pack_sent,
                  connections = @connections,
                  pack_errors = @pack_errors,
                  total_read = @total_read,
                  total_write = @total_write,
                  total_errors = @total_errors
      end

      /*
      **  Now print out old and new monitor values.
      */
      set nocount on
      select @interval = datediff(ss, lastrun, @now)
          from master.dbo.spt_monitor
      /* To prevent a divide by zero error when run for the first
      ** time after boot up
      */
      if @interval = 0
          select @interval = 1
      select last_run = lastrun, current_run = @now, seconds = @interval,
          cpu_busy_total = convert(int, ((@cpu_busy * @mspertick/ 1000)),
          cpu_busy_current = convert(int, (((@cpu_busy - cpu_busy)
              * @mspertick/ 1000)),
          cpu_busy_percentage = convert(int, ((((@cpu_busy - cpu_busy)
              * @mspertick/ 1000* 100/ @interval),
          io_busy_total = convert(int, ((@io_busy * @mspertick/ 1000)),
          io_busy_current = convert(int, (((@io_busy - io_busy)
              * @mspertick/ 1000)),
          io_busy_percentage = convert(int, ((((@io_busy - io_busy)
              * @mspertick/ 1000* 100/ @interval),
          idle_total = convert(int, ((convert(bigint,@idle* @mspertick/ 1000)),
          idle_current = convert(int, (((@idle - idle)
              * @mspertick/ 1000)),
          idle_percentage = convert(int, ((((@idle - idle)
              * @mspertick/ 1000* 100/ @interval),
          packets_received_total = @pack_received,
          packets_received_current = @pack_received - pack_received,
          packets_sent_total = @pack_sent,
          packets_sent_current = @pack_sent - pack_sent,
          packet_errors_total = @pack_errors,
          packet_errors_current = @pack_errors - pack_errors,
          total_read = @total_read,
          current_read = @total_read - total_read,
          total_write = @total_write,
          current_write =    @total_write - total_write,
          total_errors = @total_errors,
          current_errors = @total_errors - total_errors,
          connections_total = @connections,
          connections_current = @connections - connections
      from master.dbo.spt_monitor

      /*
      **  Now update spt_monitor
      */
      update master.dbo.spt_monitor
          set
              lastrun = @now,
              cpu_busy = @cpu_busy,
              io_busy = @io_busy,
              idle = @idle,
              pack_received = @pack_received,
              pack_sent = @pack_sent,
              connections = @connections,
              pack_errors = @pack_errors,
              total_read = @total_read,
              total_write = @total_write,
              total_errors = @total_errors

       

       

      版本控制

      數據庫開發人員總在想,每次修改了函數/存儲過程,我們都得自己做備份,用以歷史參考,當發現錯誤的時候,可以回滾。在SQL Monitor里面,這個是全自動的。

       

      版本控制的思想來自這里:http://www.sqlteam.com/article/using-ddl-triggers-in-sql-server-2005-to-capture-schema-changes

       

      原理就是用數據庫DDL觸發器記錄每個DDL操作,自增版本,并存儲到一個表中。

       

       

      關鍵代碼 

       

       

      SET ANSI_NULLS OFF
      GO
      SET QUOTED_IDENTIFIER OFF
      GO
      SET ANSI_NULLS ON
      GO
      SET QUOTED_IDENTIFIER ON
      GO
      IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[VERSION_CONTROL_TABLE]'AND type in (N'U'))
      BEGIN
      CREATE TABLE [dbo].[{0}](
          [ID] [bigint] IDENTITY(1,1NOT NULL,
          [databasename] [varchar](256NULL,
          [eventtype] [varchar](50NULL,
          [objectname] [varchar](256NULL,
          [objecttype] [varchar](25NULL,
          [sqlcommand] [nvarchar](maxNULL,
          [loginname] [varchar](256NULL,
          [hostname] [varchar](256NULL,
          [PostTime] [datetime] NULL,
          [Version] [int] NOT NULL,
       CONSTRAINT [PK_VERSION_CONTROL_TABLE] PRIMARY KEY CLUSTERED 
      (
          [ID] ASC
      )WITH (IGNORE_DUP_KEY = OFFON [PRIMARY]
      ON [PRIMARY]
      END

      GO

      SET ANSI_NULLS ON
      GO
      SET QUOTED_IDENTIFIER ON
      GO

      CREATE TRIGGER [TRG_VERSION_CONTROL_TABLE}]
      ON DATABASE
      FOR CREATE_PROCEDURE, ALTER_PROCEDURE, DROP_PROCEDURE,
      CREATE_TABLE, ALTER_TABLE, DROP_TABLE,
      CREATE_FUNCTION, ALTER_FUNCTION, DROP_FUNCTION,
      CREATE_TRIGGER, ALTER_TRIGGER, DROP_TRIGGER,
      CREATE_VIEW, ALTER_VIEW, DROP_VIEW,
      CREATE_INDEX, ALTER_INDEX, DROP_INDEX

      AS

      SET NOCOUNT ON

      DECLARE @CurrentVersion int
      DECLARE @CurrentID int
      DECLARE @DatabaseName varchar(256)
      DECLARE @ObjectName varchar(256)
      DECLARE @data XML

      SET @data = EVENTDATA()

      INSERT INTO dbo.VERSION_CONTROL_TABLE(databasename, eventtype,objectname, objecttype, sqlcommand, loginname,Hostname,PostTime, Version)
      VALUES(
      @data.value('(/EVENT_INSTANCE/DatabaseName)[1]''varchar(256)'),
      @data.value('(/EVENT_INSTANCE/EventType)[1]''varchar(50)'),  -- value is case-sensitive
      @data.value('(/EVENT_INSTANCE/ObjectName)[1]''varchar(256)'), 
      @data.value('(/EVENT_INSTANCE/ObjectType)[1]''varchar(25)'), 
      @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]''varchar(max)'), 
      @data.value('(/EVENT_INSTANCE/LoginName)[1]''varchar(256)'),
      HOST_NAME(),
      GETDATE(),
      0
      )

      SET @CurrentID = IDENT_CURRENT('VERSION_CONTROL_TABLE')
      SELECT @DatabaseName = databasename, @ObjectName = objectname FROM VERSION_CONTROL_TABLE WHERE ID = @CurrentID
      IF (@DatabaseName IS NOT NULL AND @ObjectName IS NOT NULL)
      BEGIN
          SELECT @CurrentVersion = MAX(Version) FROM VERSION_CONTROL_TABLE WHERE databasename = @DatabaseName AND objectname = @ObjectName
          UPDATE VERSION_CONTROL_TABLE SET Version = ISNULL(@CurrentVersion0+ 1 WHERE ID = @CurrentID
      END
      GO
      ENABLE TRIGGER [TRG_VERSION_CONTROL_TABLE] ON DATABASE

       

       

      SQL Monitor會全自動給你的所有腳本修改做版本記錄。你可以隨時查看在什么時候哪個機器用什么身份修改了哪個對象的腳本。

       

       

      SQL Monitor內置版本比較,你可以清楚知道不同的版本的差異。 

       

       

      活動監控

       

       

       

      上圖清晰顯示所有系統的活動進程,每個進程當前執行什么語句。

       

      獲取進程列表

       

      View Code
      --To get processes
      SELECT s.session_id AS spid, s.login_time, s.host_name AS hostname, s.host_process_id AS hostprocess, s.login_name AS loginname, s.logical_reads AS physical_io, s.cpu_time AS cpu, s.program_name, 0 AS dbid, s.last_request_start_time AS last_batch_begin, CASE WHEN status = 'running' THEN GETDATE() ELSE dateadd(ms, s.cpu_time, s.last_request_end_time) END AS last_batch_end, s.status FROM sys.dm_exec_sessions s JOIN sys.dm_exec_connections c ON s.session_id = c.session_id

       

       

      獲取任務列表

      View Code
      --To get jobs
      SELECT job_id AS spid, name AS program_name, 0 AS dbid, 0 AS cpu, 0 AS physical_io, NULL AS login_time, NULL AS last_batch_begin, NULL AS last_batch_end, NULL AS status, NULL AS hostname, NULL AS hostprocess, NULL AS cmd, NULL AS loginname FROM msdb.dbo.sysjobs

       

       

      分析

      這是商業級的數據與性能分析,SQL Monitor自動給你的系統、數據庫、數據表、索引等進行分析。

       

       

       

      基本原理是首先利用master.sys.xp_fixeddrives獲取磁盤的剩余空間,然后:

       

       

      //database & disk free space
              var databases = GetDatabasesInfo();
              var files = new List<tuple<bool, />>();
              databases.AsEnumerable().ForEach(d =>
              {
                  var database = GetDatabaseInfo(d["name"].ToString());
                  database.AsEnumerable().ForEach(f =>
                  {
                      files.Add(new Tuple<bool, />(Convert.ToInt32(f["type"]== 1, f["physical_name"].ToString(), Convert.ToInt64(Convert.ToDecimal(f["Size"]/ Size1K)));
                  }
                  );
              });
              var spaces = new Dictionary<string, />>();
              //MB free
              var driveSpaces = Query("EXEC master.sys.xp_fixeddrives");
              driveSpaces.AsEnumerable().ForEach(s =>
              {
                  //could not use name but rather index, because the column name will change according to locale
                  spaces.Add(s[0].ToString(), new KeyValue<long/>(Convert.ToInt64(s[1]), 0));
              });
              files.ForEach(f =>
              {
                  //maybe some access issues
                  try
                  {
                      var drive = f.Item2.Substring(01);
                      if (spaces.ContainsKey(drive))
                      {
                          spaces[drive].Value += f.Item3;
                      }
                  }
                  catch (Exception)
                  {
                      //mmmm.....what can we do, mate?
                  }
              });
              spaces.ForEach(s =>
              {
                  if (s.Value.Key < s.Value.Value / 100 * Settings.Instance.DatabaseDiskFreeSpaceRatio)
                  {
                      analysisResult.Add(new AnalysisResult { ResultType = AnalysisResultTypes.DiskFreeSpace, ObjectName = s.Key, ReferenceValue = s.Value.Key, CurrentValue = s.Value.Value, Factor = Settings.Instance.DatabaseDiskFreeSpaceRatio + SizePercentage });
                  }
              });

              //database data file & log file space
              databases.AsEnumerable().ForEach(d =>
              {
                  var name = d["name"].ToString();
                  if (!systemDatabases.Contains(name))
                  {
                      var database = GetDatabaseInfo(name);
                      var databaseSpace = new Dictionary<databasefiletypes, /> { { DatabaseFileTypes.Data, 0 }, { DatabaseFileTypes.Log0 } };
                      database.AsEnumerable().ForEach(f =>
                      {
                          var key = (DatabaseFileTypes)Convert.ToInt32(f["type"]);
                          databaseSpace[key] += Convert.ToInt64(Convert.ToDecimal(f["Size"]/ Size1K);
                      }
                      );
                      bool? shrink = null;
                      if (databaseSpace[DatabaseFileTypes.Log] > databaseSpace[DatabaseFileTypes.Data] / 100 * Settings.Instance.DatabaseDataLogSpaceRatio)
                          shrink = false;
                      else
                      {
                          var logSpaces = SQLHelper.Query("DBCC SQLPERF(LOGSPACE)", GetServerInfo(name));
                          var logSpace = logSpaces.Select(string.Format("[Database Name] = '{0}'", name));
                          if (logSpace.Length > 0)
                          {
                              var logSpacedUsed = Convert.ToDouble(logSpace[0]["Log Space Used (%)"]);
                              if (logSpacedUsed < Settings.Instance.DatabaseDataLogSpaceRatio)
                                  shrink = true;
                          }
                      }
                      if (shrink != null)
                          analysisResult.Add(new AnalysisResult { ResultType = AnalysisResultTypes.DatabaseLogSpace, ObjectName = name, ReferenceValue = databaseSpace[DatabaseFileTypes.Log], CurrentValue = databaseSpace[DatabaseFileTypes.Data], Factor = Settings.Instance.DatabaseDataLogSpaceRatio + SizePercentage, Key = (bool)shrink ? 1 : 0 });
                  }
              });

       

      對于表空間,使用了sp_spaceused,關鍵代碼:

       

      var tables = GetObjects(KeyTables);
      tables.AsEnumerable().ForEach(t =>
          {
              var name = t[KeyName].ToString();
              var space = Query(string.Format("EXEC sp_spaceused '{0}'", name), CurrentServerInfo);
              if (space.Rows.Count > 0)
              {
                  var row = space.Rows[0];
                  var dataSize = ToKB(row["data"]/ Size1K;
                  var indexSize = ToKB(row["index_size"]/ Size1K;
                  if (indexSize > dataSize / 100 * Settings.Instance.TableDataIndexSpaceRatio)
                      analysisResult.Add(new AnalysisResult { ResultType = AnalysisResultTypes.TableIndexSpace, ObjectName = name, ReferenceValue = dataSize, CurrentValue = indexSize, Factor = Settings.Instance.DatabaseDataLogSpaceRatio + SizePercentage, Key = (int)TableIndexSpaceRules.DataIndexSpaceRatio });
              }
          });

       

       

       

       

       

      最新版本

       

      http://sqlmon.codeplex.com/releases/view/77943

       

      主站蜘蛛池模板: 精品福利一区二区三区免费视频| 色爱综合激情五月激情| 少妇粗大进出白浆嘿嘿视频| 亚洲精品亚洲人成人网| 麻豆精品一区二区三区蜜臀| 中文字幕日韩一区二区不卡| 欧美成人精品三级在线观看| 国产99久久亚洲综合精品西瓜tv| 久久天天躁狠狠躁夜夜2020老熟妇 | 国产粉嫩系列一区二区三| 日本边吃奶边摸边做在线视频 | 成人网站免费观看永久视频下载 | 亚洲熟妇精品一区二区| 国产精品ⅴ无码大片在线看| 亚洲综合黄色的在线观看| japan黑人极大黑炮| 麻豆人人妻人人妻人人片av| 亚洲精品区二区三区蜜桃| 九九热在线视频观看最新| 亚洲精品美女久久久久9999 | 成人午夜av在线播放| 国语精品自产拍在线观看网站| 强行交换配乱婬bd| 人妻一区二区三区人妻黄色| 福利一区二区在线播放| 精品无码人妻一区二区三区| 亚洲偷自拍另类一区二区| 华人在线亚洲欧美精品| 饶阳县| 成人性生交片无码免费看| 久久毛片少妇高潮| 七台河市| 香蕉亚洲欧洲在线一区| 99久久精品久久久久久清纯| 92精品国产自产在线观看481页| 国产亚洲精品自在久久vr| 艳妇乳肉豪妇荡乳xxx| 东方四虎在线观看av| 国产啪视频免费观看视频| 无卡无码无免费毛片| 欧美极品色午夜在线视频|