有什么方法可以加快这个 sql 查询的速度吗?

Any way to speed up this sql query?

我有以下 Postgres 查询,该查询需要 10 到 50 秒才能执行。

SELECT m.match_id FROM match m
WHERE m.match_id NOT IN(SELECT ml.match_id FROM message_log ml)
AND m.account_id = ?

我在 match_idaccount_id

上创建了索引
CREATE INDEX match_match_id_account_id_idx ON match USING btree
  (match_id COLLATE pg_catalog."default",
   account_id COLLATE pg_catalog."default");

但是还是查询了很长时间。我该怎么做才能加快速度并提高效率?当我执行其中一些查询时,我的服务器负载达到 25。

NOT IN (SELECT ... ) 可能要贵得多,因为它必须单独处理 NULL。当涉及 NULL 值时,它也可能很棘手。通常 LEFT JOIN / IS NULL (或其他相关技术之一)更快:

  • Select rows which are not present in other table

应用于您的查询:

SELECT m.match_id
FROM   match m 
LEFT   JOIN message_log ml USING (match_id)
WHERE  ml.match_id IS NULL
AND    m.account_id = ?;

最好的索引是:

CREATE INDEX match_match_id_account_id_idx ON match (account_id, match_id);

或者只是在(account_id)上,假设match_id在两个表中都是PK。您在 message_log(match_id) 上也已经有了所需的索引。否则也创建那个。

此外,您的索引定义中的 COLLATE pg_catalog."default" 表明您的 ID 列是 character types, which is typically inefficient. Should typically better be integer types

根据您目前所展示的内容,我有根据的猜测:可能还有更多问题。