设计问题:在SQL表中存储和检索增量的最佳方法

时间:2018-12-25 19:47:16

标签: sql sql-server query-optimization storage delta

我有一个历史表,其中包含许多价格列,一次只更改了几列。目前,我只是将所有数据作为新记录插入,这种更改每秒可能发生100多次。因此,这导致表大小的快速增长。

我正在尝试为表找到更好的设计,以将表的大小保持为最小,并在需要时检索表的最佳查询。我不太担心数据检索的性能,但是在用于报表时应该放在中间。优先考虑的是将表的大小保持在最小。

该历史表中的数据不是每天检索的。为此,我有一个诸如* 1 Current Design的交易表。 这是我的实施细节。

1)当前设计

enter image description here

2)计划的设计-1

enter image description here

问题:

1)如果我使用上面的表结构,什么是最佳查询,以获得类似于当前设计1所示的结果

3)计划的设计-2

enter image description here enter image description here

问题:

1)与计划的设计#1相比,将达到多少性能。

2)另外,如果我沿那条路线去走,什么是最佳查询,以得到与当前设计#1中所示结果相同的结果?

结束问题:

我假设计划设计1将占用更多的表空间,而计划设计2将占更多空间。但是计划的设计2将花费更多时间来检索查询。我认为有什么情况会出错吗?

编辑:我只有插入到此表。对此不做任何更新或删除。

2 个答案:

答案 0 :(得分:1)

我有类似的情况,我每10秒钟加载一堆温度传感器。当我使用MSSQL的快速版本时,我希望数据库的最大大小为10GB,所以我变得非常有创意,以使其尽可能长久地使用。 我的表布局与您的表布局几乎相同,因为我有1个时间戳+ 30个值列+另外30个标志列。

  • 值列为数字(9,2)
  • 如果该值与之前的值相同(足够),则我将它们存储为NULL而不是重复该值。
  • 标志列是位,指示值是“外推”还是实际来源(此后)

我还有另一个表,其中包含每个传感器的以下信息:

  • 上一次更新传感器;这样,如果有一个新值,我可以轻松地决定这是否只需要在表的末尾插入一个新的插入值,或者是否需要遍历在现有数字之间插入/更新一个值的所有逻辑。 li>
  • 最新条目的值
  • 所述传感器的灵敏度;这样,我就不必对其进行硬编码,并且可以基于每个传感器进行设置

无论如何,现在我的信息流是,我有几个程序分别读取来自不同来源(arduino,web等)的数据,并将其转储到.csv文件中,然后再读取一个“解析器”程序,该程序读取这些文件偶尔会进入数据库。由于我是按1而不是基于行的方式加载值,因此效率不是很高,但是我现在每秒处理约3500个值,因此我不太担心。我会同意,仅当按历史顺序加载值时才是如此,因为我使用的是帮助器表。

目前我那里有将近一年的信息,对应于

  • 2.209.883行
  • 5.799.511值分布在18个传感器上(是的,我还有足够的空间容纳12个而不需要更改表格)

这意味着我只填写了15%的字段,或者换句话说,当我填写每条记录而不是在重复的情况下放入NULL时,我几乎有8%乘以那里的数字。

关于空间要求:我决定昨晚重新加载所有数字以“取乐”,但注意到,即使大多数.csv文件按历史记录出现,它们也会在从Jan到Dec的范围内创建一系列列,然后再进行另外几列从一月到十二月等。这导致了很多碎片:实际上是70%!当时该表需要282Mb的磁盘空间。 然后,我重新构建了表,使碎片降低到0%,保留空间降低到118Mb(!)。

对我来说,这已经足够了

  • 该表不太可能很快会超过10GB的限制,尤其是如果我坚持不时地(在线)重建它时。
  • 加载数据足够快(尽管全年重新加载花费了几个小时)
  • 报告足够快(到目前为止,尚未尝试将任何“交互式”报告工具连接到它;但是对于excel中的一些简单图形,它可以很好地恕我直言)。

仅供参考:为了进行报告,我创建了一个评估程序简单的存储过程,该过程为给定的一组列选择了从头到尾的范围;将其转储到临时表中,然后通过找出NULL范围,然后用该范围之前的值填充这些值来填充空白。尽管获取“第一个”值有时会花费一些时间,但由于我无法预测应该寻找最后一个值的时间(有时没有),所以此方法效果很好。 要解决此问题,我添加了另一个过程,可以为每个“小时”时间戳外推值。这样一来,报告回退时间就不会超过1小时。读数表中的标记列指示给定字段的记录上的值是否外推。 (注意:这使得过去更新值的问题更多,但并非不可能)

希望这有助于您的努力,祝您好运!

答案 1 :(得分:0)

实际上,我认为您有更好的计划。您可以使用SQL Server 2016中的临时表。 此类型由sql管理,以最佳方式跟踪表的更改。 访问此链接:https://docs.microsoft.com/en-us/sql/relational-databases/tables/temporal-tables?view=sql-server-2017