设置
我们有一个多租户应用程序,大约有 1000 个客户。当客户流失时,我们会在一段时间后删除他们的所有数据。我们有一些非常大的表,我们正在考虑使用分区来按客户拆分它们。
问题
1000 个租户(客户)是很多分区 - 在 PostgreSQL 上这样做合理吗?
更多细节
目前,我们的租户之间的分离是通过account_id
数据库中所有表上的列来实现的。有几张桌子都很大。例如,有一个event
表(我对分区感兴趣的表)包含审核日志和我们应用程序中发生的所有事件的其他事件。
以下是有关事件表的一些事实:
account_id
非常不均匀,5% 的帐户拥有 50% 的数据。author_id
等等)account_id
)。删除的数据可能有数百万行。没有更新。删除大帐户的情况很少见,目前并不是一个大的性能问题。account_id
+ id
)或给定时间段内的所有事件。并不总是设定时间段。account_id
始终出现在查询中。可能的解决方案
分区方式account_id
:
优点:
DROP TABLE
.WHERE account_id = 123
缺点:
按时间戳分区:
优点:
缺点:
我正在尝试删除incoming
每秒有 100 个事务的繁忙数据库中的一个表(称为 )。表本身是空的(truncate table
之前执行过)。如果我尝试在其他各种正在等待的表上执行drop table incoming
大量事务drop table
显然不好。
我开始一一删除索引、约束和列,以确定是什么阻止了表删除,并找到了导致锁定的外键约束。这是“最终”incoming
表架构:
create table incoming
(
account_id integer
constraint incoming_account_id_fkey
references account
);
Run Code Online (Sandbox Code Playgroud)
从被阻止的查询来看(ticket
以下表为例),看起来并不是account
表查询被阻止,而是在一个繁忙的表上的查询ticket
,该表具有该表的外键account
。为什么删除 FK inincoming
块查询ticket
?
这是 3 个表的概要:
incoming
- 这是我要删除的外键所在的位置(参见下面的架构)。account
- 外键参考表。ticket
- 具有外键约束的繁忙表(选择、插入、更新等)account
。我尝试做的事情:
我尝试禁用 table: 上的触发器ALTER TABLE incoming DISABLE TRIGGER ALL;
并设置 FK DEFERRABLE: ALTER TABLE incoming ALTER CONSTRAINT incoming_account_id_fkey …