Postgres加入了min*+超级慢地分组

问题描述

这是我的查询的样子:

SELECT disTINCT user.id AS user_id,messaged_date
FROM users
         JOIN (
           SELECT MIN(message_date) AS messaged_date,user_id
           FROM messages
           GROUP BY user_id
     ) messages_join ON user.id = messages_join.user_id
WHERE (user.client_id IN ('1234')
    AND user.status IN ('statusA')
);
  1. messages表具有两个列-> user_idmessaged_date。我既有索引,也有多列索引(user_id,messaged_data asc nulls last)
  2. messages表很大。大小约为50Gb。
  3. 查询要花费年龄(5分钟以上)才能运行。
  4. 如果删除该联接,它将在1秒内返回。
  5. 我想每user_id排一行

如何使查询执行更快?显然,在min加上group_by上的联接是原因。 (EXPLAIN确认了这一点。)

我尝试了loose index scan,aka a "skip scan",它本身表现不错,但是加入结果时却无济于事。

解决方法

这是问题的原始版本。

子查询非常奇怪。看来您只想exists

SELECT u.id AS user_id
FROM users u
WHERE u.client_id IN ('1234') AND
      u.status IN ('statusA') AND
      EXISTS (SELECT 1
              FROM messages m
              WHERE m.user_id = u.id
             );

这可以利用messages(user_id)上的索引。

,

也许您想要这样:

SELECT DISTINCT ON (users.id)
       users.id AS user_id,messages.message_date AS messaged
FROM users
   JOIN messages
      ON users.id = messages.user_id
WHERE users.client_id = '1234'
  AND users.status = 'statusA'
ORDER BY users.id,message.message_date;

可以加快查询速度的索引:

CREATE INDEX ON users (client_id,status);
CREATE INDEX ON messages (user_id);

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...