对于PostgreSQL表来说,多大才算太大?

我正在为我的公司设计一个RoR项目,我们的开发团队已经遇到了一些关于设计的争论,特别是数据库。

我们有一个名为Message的模型需要持久化。这是一个非常非常小的模型,除了id之外只有三个db列,但是当我们投入生产时,可能会有很多这样的模型。我们每天有多达100万次的插入。模型只会被两个可以被索引的外键搜索。同样,这些模型永远不会被删除,但我们也不必在它们三个月大的时候保留它们。

所以,我们想知道的是,在Postgres中实现这个表是否会带来重大的性能问题?有没有人有使用大型SQL数据库的经验告诉我们这是否会是个问题?如果是的话,我们应该选择什么?

148537 次浏览

每个表中的行本身不会成为问题。

所以粗略地说,每天100万行,持续90天就是9000万行。我不认为Postgres不能在不了解您所做事情的所有细节的情况下处理这些问题。

根据您的数据分布,您可以混合使用索引、过滤索引和某种类型的表分区来加快速度,一旦您发现可能存在或可能没有性能问题。在我所知道的任何其他RDMS上,您的问题都是相同的。如果你在一个过程中只需要3个月的数据设计来删除你不需要的数据。这样,您将在表上拥有一致的数据量。幸运的是,你知道有多少数据会存在,测试它的容量,看看你会得到什么。测试一个包含9000万行的表可能像下面这样简单:

select x,1 as c2,2 as c3
from generate_series(1,90000000) x;

https://wiki.postgresql.org/wiki/FAQ

Limit   Value
Maximum Database Size       Unlimited
Maximum Table Size          32 TB
Maximum Row Size            1.6 TB
Maximum Field Size          1 GB
Maximum Rows per Table      Unlimited
Maximum Columns per Table   250 - 1600 depending on column types
Maximum Indexes per Table   Unlimited

另一种方法是使用>1亿行用于将表聚集在查询中最常用的索引上。在数据库的"off"个小时。我们有一张>2.18亿行并发现了30倍的改进。

此外,对于一个非常大的表,在外键上创建索引是个好主意。

例子:

  1. 假设我们在名为ccbank的数据库中有一个名为investment的表。
  2. 假设查询中最常用的索引是(bandkid,record_date)

下面是创建和聚类索引的步骤:

  1. psql -c "drop index investment_bankid_rec_dt_idx;" ccbank
  2. psql -c "create index investment_bankid_rec_dt_idx on investment(bankid, record_date);"
  3. psql -c "cluster investment_bankid_rec_dt_idx on investment;"
  4. vacuumdb -d ccbank -z -v -t investment

在步骤1-2中,我们用一个新的优化的索引替换旧的索引。在步骤3中,我们将表聚类:这基本上是将DB表按索引的物理顺序放置,这样当PostgreSQL执行查询时,它就会缓存最有可能的下一行。在第4步中,我们清空数据库以重置查询计划器的统计信息。