Search code examples
sqlperformancedenormalization

Best way to store a value to query latest without de-nomalizing?


This is the structure of my Table which stores meter readings for machines. I need to save all readings so I can retrieve readings for any date and validate any new readings.

enter image description here

I have an index on AssetID, ForDate Descending so the latest readings are at the top.

It's taking too long to find the latest meter reading for a machine with this table. I don't want to de-normalize the meter reading against the Machine as it would cause concurrency issues when two or more people try to enter readings at once.

Any suggestions to make this faster?

EDIT: This is my LINQ2SQL Query

        Dim res = From a In db.AssetMeterReadings Where _
              a.AssetID = ast.AssetID And a.ForDate <= dAt.Date _
              And a.isInactive = False _
              Order By a.ForDate Descending, a.ApproximateReading Descending Take 1

Solution

  • Are you trying to get just one row or the latest entry for many/all AssetID? If you are trying to query for many the latest entry for many different assets then the index will not help you much.

    I would suggest you to

    1. Add a now column IsLatestReading(bit)
    2. Add trigger for INSERT, UPDATE, DELETE to keep column IsLatestReading just be careful with the recursive trigger it will cause

      the trigger something like:

      update MyTable set IsLatestReading = 0 
      inner join DELETE on DELETE.AssetID = MyTable and IsLatestReading = 1
      
      update table  MyTable set IsLatestReady = 1
      inner join INSERTED on INSERTED.MeterReadingID = MyTable.MeterReadingID
      
    3. create index on IsLatestReading DESC, AssetID, ForDate

    Note: If you use bulk insert to load the readings, you'll won't need the trigger, just an update to the column would do...