SQL 查询性能、归档与状态变化

SQL query performance, archive vs status change

开门见山,我尝试在 google 和 SO 上搜索,但找不到我要找的东西。可能是因为我的搜索措辞不正确。

我的问题是,
我有几张桌子,每年可容纳 1,000 行到 100,000 行之间的任何地方。我想弄清楚,我/我应该如何处理数据归档?我在数据库方面经验不足,但下面是我想出的一些方法,我不确定哪种方法更好。当然要考虑到性能和编码的难易程度。我正在使用 Java 1.8、Sql2o 和 Postgres。

方法一 每年将数据归档到单独的数据库中。
我不太喜欢这种方法,因为当我们想要搜索旧数据时,我们的应用程序将需要搜索到不同的数据库,为此添加更多代码对我来说会很麻烦。

方法二 将超过 2-3 年的数据存档到单独的数据库中。
并在线路上使用状态来提高性能。 (参见方法 3)这是我倾向于作为 'Optimal' 解决方案的方法,其中代码不那么复杂,但也由 DB 保持相对干净。

方法三 只要有每行的状态(例如:A=active,R=Archived)可能会提高查询的性能。只要有一个"select * from table where status = 'A' "来减少查询的数量要查看的行。

每年 100,000 行并不算多。 [1]

没有必要将它移到一个单独的地方。如果您已经有了良好的索引,那么多年来您几乎肯定不会注意到任何性能下降。

但是,如果您想绝对确定,可以添加一个 year 列并为其创建一个索引(或将其添加到您现有的索引中)。但实际上,仅在您知道需要它的 table 时执行此操作。例如,如果您的 table 已经有一个作为索引一部分的 date 列,则您不需要单独的 year 列。

[1] 除非您有数千列 and/or 包含大型二进制 blob 的列 - 此处似乎并非如此。

正如 Vog 所说,100,000 行并不算多。 1,000,000 或 5,000,000 也不是 - 您的 table 可能增长到的大小。

在许多数据库中,您可以使用聚集索引,其中第一个键是 "active" 列。但是,Postgres 并不真正支持聚集索引。

相反,我建议您查看 table partitioning。这是一种将底层存储拆分为不同 "files" 的方法。您可以使用 where 子句中的分区键轻松指定查询读取一个或多个分区。

对于您的特定用例,我会进一步建议仅查看活动数据的数据。这只会读取一个分区,因此性能应该与读取仅包含最新数据的 table 几乎相同。

就是说,我不确定按 active 标志或 year 进行分区是否更好。这取决于您访问数据的方式,尤其是较旧的数据。