【问题标题】:postgres: NOT IN array instead of NOT EXISTS expressionpostgres:NOT IN 数组而不是 NOT EXISTS 表达式
【发布时间】:2017-07-31 00:17:19
【问题描述】:

我的项目随机匹配一对用户。他们可以退出游戏并与其他用户随机匹配。

我不希望有一段时间可以一次又一次地匹配 2 个用户。

我将所有数据(如 user_id、lang、gender 等)保存在 postgres 表中。

为了暂时不再匹配它们,我使用 redis 排序列表和 unix time 来存储匹配的用户对。我决定使用 redis 是因为我的项目每天要存储 100 万对情侣。

当我必须将一个用户与另一个用户匹配时,我会从 redis 获得在最后 x 分钟内与他匹配的用户列表,然后我将它们传递给“其中 user_id 不在 ()”中(它们永远不会超过200,如果我将其限制为 200),当我运行查询以查找与他匹配的可用用户时。

这样我就不能使用应该比IN 更快的exists 或join 表单。然后我是否应该考虑使用 postgres 来存储这对夫妇,尽管我应该每天写 100 万个(当然我可以在一段时间后删除这些行),使用 EXISTS 或 JOIN 运行查询而不是 NOT IN 传递一个元组?.

我想知道表演。

【问题讨论】:

  • 测试加入VALUES 表表达式作为FROM 中的子查询。 IIRC 对于很多值来说是最快的。我前段时间写了一篇关于它的帖子,搜索我的历史。

标签: postgresql performance redis


【解决方案1】:

这里得做一些概率...

假设您有 Nu = 100 万在线用户。

用户今天点击“匹配”Nm = 200 次。

用户再次点击“匹配”。我们希望将它们与不属于 200 个先前匹配列表的随机用户进行匹配。

随机选择一个用户,我们只有 Nm/Nu 的概率选择在最近 200 次匹配中与该用户匹配的用户。这只是 200/10000000 = 0.002% 的概率。

在这种情况下,由于过去的匹配列表没有存储到 postgres 中,因此更有意义的是:

  • 只需获取匹配项,无需将 200 个整数插入 SELECT...
  • 然后检查匹配的用户是否在之前的匹配列表中
  • 如果是这样,请重复。

您只有很小的机会不得不再次运行循环,但每次查询都会减轻(不再需要 postgres 解析 200 个整数)。

现在,如果您将匹配数据存储到 postgres 而不是 redis... 每天 1M INSERTS 是 11.5 INSERTS/秒,这可以忽略不计...那么您可以通过一个查询来实现这一点。只要 pg 在随机数生成器上使用嵌套循环并在 LIMIT 1 处停止,它就可以正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-24
    • 2016-02-11
    • 2014-12-29
    • 2015-02-17
    • 1970-01-01
    • 2017-12-05
    • 2013-11-18
    • 2015-07-06
    相关资源
    最近更新 更多