存储值以查询最新值而不进行去正规化的最佳方法?

时间:2013-09-16 03:32:20

标签: sql performance denormalization

这是我的表格结构,用于存储机器的仪表读数。我需要保存所有读数,以便我可以检索任何日期的读数并验证任何新的读数。

enter image description here

我有一个AssetID索引,ForDate Descending所以最新读数位于顶部。

使用此表找机器的最新仪表读数需要很长时间。我不想对机器的抄表进行去标准化,因为当两个或更多人试图一次输入读数时会导致并发问题。

有什么建议可以加快速度吗?

编辑:这是我的LINQ2SQL查询

        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

2 个答案:

答案 0 :(得分:1)

我认为您需要运行性能分析器来了解您的查询是否实际使用此索引。您没有提到它是什么RDBMS,但在SQL-Server中,查询分析器中有一个“显示执行计划”选项。

如果您有列的单个索引,有时查询执行得更快,例如Index1 ON AssetID,Index2 ON ForDate。另外,我不相信你应该指定订单。试着看看个别指数是如何运作的

答案 1 :(得分:1)

您是否只想获得一行或许多/所有AssetID的最新条目? 如果您尝试查询许多不同资产的许多最新条目,那么该索引对您没有多大帮助。

我建议你

  1. 添加一个现在的专栏IsLatestReading(bit)
  2. 添加trigger for INSERT, UPDATE, DELETE以保持列IsLatestReading 只需注意它将导致的递归触发器

    触发器如下:

    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

  4. IsLatestReading DESC, AssetID, ForDate

    注意:如果您使用批量插入来加载读数,那么您将不需要触发器,只需对列进行更新即可...