Search code examples
sql-serversql-server-2008-r2viewindexed-view

get the latest record using an indexed view


I am working on a monitoring project, and every time I collect the data I generate a new ID for that collection.

I would like to have the latest code in an indexed view.

SELECT THE_ID = MAX(THE_ID)  FROM [dbo].[monit_server_space_by_drive]

something like this:

CREATE VIEW V_LAST_ID 
WITH SCHEMABINDING
AS
SELECT THE_ID = MAX(THE_ID)  FROM [dbo].[monit_server_space_by_drive]

CREATE UNIQUE CLUSTERED INDEX UC_IDX_V_LAST_ID  ON V_LAST_ID (THE_ID)

Is this possible or are there any alternatives?

this is how I intend to use it:

SELECT 
   M.[THE_ID]
  ,M.[serverid]
  ,s.SQLServerName
  ,s.[Environment]
  ,M.[DRIVE]
  ,M.[Volume_Size_GB]
  ,[VolumeUsed_GB] = CAST (M.[VolumeUsed_MB] / 1024.00 AS NUMERIC (18,2))
  ,M.[VolumeSpaceAvailable_GB]
 , DrivePercentUsed = 100 - M.[VolumePercentAvailable]
  ,M.[VolumePercentAvailable]

  FROM [dbo].[monit_server_space_by_drive] M
  INNER JOIN DBO.V_LAST_ID  V 
      ON M.THE_ID = V.THE_ID
  INNER JOIN [dbo].[tblServers] S
      ON M.serverid = s.ServerID
  order by M.[ClusterName]

The primary key of table [dbo].[monit_server_space_by_drive] is made up of three fields:

USE [Monitoring]
GO

ALTER TABLE [dbo].[monit_server_space_by_drive] ADD  CONSTRAINT [PK_monit_server_space_by_drive] PRIMARY KEY CLUSTERED 
(   [THE_ID] ASC,
[serverid] ASC,
[volumeID] ASC
)ON [FGMONITORING]

The table definition:

CREATE TABLE [dbo].[monit_server_space_by_drive](
[THE_ID] [int] NOT NULL,
[serverid] [int] NOT NULL,
[ClusterName] [nvarchar](260) NOT NULL,
[nodeid] [int] NOT NULL,
[DRIVE] [nchar](1) NULL,
[volumeID] [int] NOT NULL,
[LastSync] [datetime] NULL,
[Volume_Size_MB] [numeric](18, 2) NULL,
[Volume_Size_GB] [numeric](18, 2) NULL,
[VolumeSpaceAvailable_MB] [numeric](18, 2) NULL,
[VolumeSpaceAvailable_GB] [numeric](18, 2) NULL,
[VolumePercentAvailable] [numeric](5, 2) NULL,
[dt] [datetime] NULL,
[_year] [smallint] NULL,
[_month] [tinyint] NULL,
[_day] [tinyint] NULL,
[_week] [tinyint] NULL CONSTRAINT [DF_monit_server_space_by_drive__week]  DEFAULT ((0)),
[_hour] [tinyint] NULL,
[_min] [tinyint] NULL,
[_weekday] [tinyint] NULL,
[VolumeUsed_MB]  AS ([volume_size_MB]-[volumeSpaceAvailable_MB]) PERSISTED,
 CONSTRAINT [PK_monit_server_space_by_drive] PRIMARY KEY CLUSTERED 
 (
[THE_ID] ASC,
[serverid] ASC,
[volumeID] ASC
) ON [FGMONITORING_INDEX]
) ON [FGMONITORING]

Below is an example of the data this table holds. Each time I gather data for connection THE_ID is increased by one. Within the same THE_ID I have all the servers in my environment.

enter image description here


Solution

  • If this were to work then each time you inserted a new record, the index for the view would have to be updated.

    Why not do this more directly using a trigger to update the last ID into a tiny table.

    CREATE TABLE DBO.V_LAST_ID( [THE_ID] [int] NOT NULL );
    
    INSERT DBO.V_LAST_ID (THE_ID) VALUES (0); --Starting row
    
    CREATE TRIGGER Dbo.KeepV_LAST_IDNumber ON [dbo].[monit_server_space_by_drive]
    AFTER INSERT AS
    BEGIN
       DECLARE @MaxInserted int;
    
       SELECT @MaxInserted = MAX(THE_ID) FROM inserted;
    
       UPDATE DBO.V_LAST_ID
       SET THE_ID = @MaxInserted
       WHERE THE_ID < @MaxInserted;
    END
    

    You can then use this table as you intended instead of the view.