3

现在,我正在为一个应用程序开发数据库模式,该应用程序需要对几组不同的数字数据进行版本控制,这些数字数据必须连接在一起才能在视图中使用。该应用程序要求我们能够“回顾”并找到这些多个变量在任意时间点的状态。

我使用子查询构建了一些视图定义,以根据任意连接条件获取各种输入,并根据time_created字段检查版本。这不是严格的 SCD2 实现,但很接近。

您可以在此处看到与我们的架构类似(尽管已大大简化)的实现:DB Fiddle 链接。真正的模式有 6 个子查询/连接。

这对我的目的非常有效,除了当我们开始将其扩展到数千个“购买”记录时,我们会产生大量的查询成本。针对 2000 多行的查询需要大约 1 秒,这不适合我们的应用程序。

想到的第一个解决方案是创建一个表,它将“购买”连接到它的各种版本化输入表,由应用程序在创建购买时创建。这应该更有效,但需要更多的模式复杂性。

任何人都可以就如何最好地规划我的模式/查询以最适合这种设置提供建议吗?

4

1 回答 1

3

我找到了一个稍微令人满意的解决方案来解决这个问题。忽略这一点我觉得有点愚蠢,但是您可以代表我将其归结为“过早优化”的情况。根据维基百科中的学术示例,我在我的 SCD 表中省略了这些end_date列。我认为这并不是特别必要,因为要“倒回”表格并找到正确的 SCD 行,您需要做的就是找到start_date小于或等于表格排序时查询日期的第一行。但这需要表格排序才能正常工作。

我的查询中的主要瓶颈是由时间戳对中等大(2500+ 行)表进行排序引起的。我设法通过添加“end_date”列并更改要使用的查询来解决此问题(简化示例):

LEFT JOIN LATERAL ( SELECT * FROM tax t
  WHERE p.time_created >= t.time_created AND p.time_created <= COALESCE(t.time_ended, '9999-12-30'::date)) current_tax ON true
....

这将查询从约 1 秒减少到 <100 毫秒。我尝试为 2500+ 行表中的字段添加索引,但这似乎对查询时间没有太大影响,但也许我在那里犯了一些错误。无论如何,这似乎更加优化。

可以在这里看到更新的 DBFiddle 。

null关于如何更好地表示这一点,或者如何更好地说明列中的值,我希望得到一些建议time_ended

于 2018-04-23T21:11:32.247 回答