【问题标题】:Fastest way to enforce a limit per UserId对每个 UserId 实施限制的最快方法
【发布时间】:2019-10-18 18:45:10
【问题描述】:

我有一个有趣的问题,我想对用户可以放置的优惠数量实施特定限制。报价保存在 postgresql(版本 10)数据库中,不应超过 1000。

我正在使用以下 sql 查询来检查用户有多少优惠并对照限制进行检查:

select count(*) from offers where offers.userId = 'b27e1d2f-c2c1-4d0b-8451-287013d7b716';

在性能指标中,我看到大部分时间都花在了这个查询上。因此我查了一下,发现:https://wiki.postgresql.org/wiki/Slow_Counting

PostgreSQL 仍然需要读取结果行以验证它们是否存在;

在查询规划器中可以看出,除了索引之外,只需要扫描一些堆提取,我认为这会减慢整个查询的速度:

Index Only Scan using offers_by_user_id_index on offers
Index Cond: (account_id = 'b27e1d2f-c2c1-4d0b-8451-287013d7b716'::uuid) | Heap Fetches: 650

- 有什么方法可以加快速度?

跟踪行数是加快检查速度的好方法吗?

感谢您的帮助!

编辑:UserId 是一个 UUID,并且 UUID 列上存在索引

【问题讨论】:

  • 您应该在userid 上有一个索引,如果这是一个数字(int),您应该将它与一个数字进行比较,'1' 是一个字符串常量,1 是一个数字
  • 其实userId是一个uuid并且存在索引,但是根据持久化offer的数量,统计的时间还是会增加很多。
  • 请显示原始的完整执行计划(最好使用explain (analyze, buffers)生成,而不是删除导入部分的精简版本(并且格式被搞砸了)

标签: sql postgresql performance


【解决方案1】:

堆提取的数量表明该表没有足够频繁地被清理。如果你手动 VACUUM 它,会加快速度吗?

【讨论】:

  • 表被频繁修改(插入/更新/删除),这可能是个问题吗?
  • 是的,如果它更新得非常快,可能很难让它保持足够的真空状态。但也许您只需将 autovac 设置更改为更具侵略性。
  • 感谢您的建议,如果真空运行更频繁,我会检查会发生什么!
  • 确实,由于表经常更换,真空运行的频率不够。
【解决方案2】:

我会说正确的工具是反规范化:

  1. 在表用户中添加列 offerCount
  2. 在用户表 userid、offersCount 上创建索引

向表中添加两个触发器

  1. 插入触发器 - 将更新 users 表并增加 offerCount 列
  2. 删除触发器 - 将更新 users 表并减少 offserCount 列

这样几乎没有延迟

注意:如果你不想更新用户的表,只需创建一个新的,只有两列

【解决方案3】:

首先,您的 id 可能是数字,因此不应该与字符串进行比较。所以:

select count(*)
from offers
where offers.userId = 1;

对于这个查询,我建议在offers(userid) 上查询。这可能会有很大帮助。

这可能是一种将 id 存储在数组中的情况。然后你可以添加:

alter table users add constraint chk_offers check (array_length(offers) <= 1000)

这也改变了插入和删除值的方式。

对于许多目的,这将运作良好。如果您关心保留有关用户/优惠的大量其他信息,例如创建日期、优惠日期、渠道等,则效果不佳。

【讨论】:

  • 感谢您的评论。用户 ID 是 UUID,我更新了示例。报价有额外的数据,那么应该在哪里保存呢?
  • user_id 上的索引是否对性能有足够的帮助?此外,问题不是关于 offer 的附加信息,而是关于 offer*/*user 组合的附加信息。
  • 是的,索引有帮助。我添加了查询计划器的结果,它告诉我这是仅索引扫描,但还显示了堆提取...
  • 用 SQL 引用,不代表是字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-14
  • 1970-01-01
  • 1970-01-01
  • 2011-12-05
  • 2016-05-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多