【问题标题】:Postgresql IN clause versus nested SELECT with JOIN performancePostgresql IN 子句与具有 JOIN 性能的嵌套 SELECT
【发布时间】:2017-06-29 04:30:30
【问题描述】:

我现在有一个运行良好的查询,但会遇到扩展问题。我找到的解决方案非常缓慢。我希望加快第二个查询的速度。

无法很好扩展的旧查询:

SELECT user.score
FROM users
WHERE
  user.id IN (
    SELECT user_id 
    FROM companies_users 
    ON companies_users.company_id = X
)

然后我会遍历不同的分数以将它们分组。分数范围从 -10 到 10。问题来自 IN SELECT 语句和迭代。返回的 user_id 可能超过一百万。

我想出的替代方案应该可以更好地扩展,但速度非常慢:

SELECT 
  COUNT(*) as total_scores,
  (SELECT COUNT(*) FROM users 
    JOIN companies_users as cu ON cu.company_id = cu.user_id
    WHERE users.score = 10 AND cu.company_id = X) as "10",
  (SELECT COUNT(*) FROM users 
    JOIN companies_users as cu ON cu.company_id = cu.user_id
    WHERE users.score = 9 AND cu.company_id = X) as "9",
...
  (SELECT COUNT(*) FROM users 
    JOIN companies_users as cu ON cu.company_id = cu.user_id
    WHERE users.score = -9 AND cu.company_id = X) as "-9",
  (SELECT COUNT(*) FROM users 
    JOIN companies_users as cu ON cu.company_id = cu.user_id
    WHERE users.score = -10 AND cu.company_id = X) as "-10"
FROM users
  JOIN companies_users as cu ON cu.company_id = cu.user_id
  WHERE cu.company_id = X

第一个查询需要迭代才能进入工作数据。第二个很好。

有没有办法将 JOIN 从嵌套的 SELECT 中拉出来?这似乎导致了第二个查询的大部分放缓。另外,在处理数百万个 id 时,第一个查询不能很好地扩展,我说得对吗?

【问题讨论】:

    标签: postgresql join count


    【解决方案1】:

    会有什么问题:

    SELECT u.score
    FROM companies_users cu
        JOIN users u ON cu.user_id = u.id
    WHERE cu.company_id=?
    GROUP BY u.score
    ORDER BY u.score
    

    ?

    另外,你有合适的索引吗?您需要在companies_users(company_id) 上建立一个索引,在users(id) 上建立一个索引。您可以尝试在 Companies_users(user_id) 上添加一个,以防万一计划者决定以相反的方式进行查询。 EXPLAINEXPLAIN ANALYZE 是你的朋友。

    【讨论】:

    • 感谢您的回复!这非常接近完美。我实际上是在寻找不同分数的计数。我使用了您的解决方案,但将选择部分更改为 u.score、count(u.score) 并获得了所有数据!再次感谢。
    猜你喜欢
    • 2022-06-10
    • 2012-10-09
    • 1970-01-01
    • 2019-01-15
    • 2010-12-01
    • 2010-11-15
    • 1970-01-01
    • 2013-02-26
    相关资源
    最近更新 更多