简单查询真的很慢

Simple query is really slow

我有这个查询需要 36 秒才能执行,但我不明白为什么或如何改进它。有帮助吗?

SELECT p.* FROM products p INNER JOIN product_store ps ON p.id = ps.product_id
INNER JOIN stores s ON s.id = ps.store_id WHERE s.city = 'Berlin' GROUP BY p.id LIMIT 16 OFFSET 0;

这些是以下数字:

SELECT count(*) FROM products;

43309

SELECT count(*) FROM product_store;

1456445

SELECT count(*) FROM stores;

155

我想这可能是为了关系 table 但 36 秒对于 16 行来说太多了。

知道如何改进这个查询吗?

编辑:

无论出于何种原因,问题都不是由 Postgres 引起的,而是由 Hibernate 引起的。查询在 pgAdmin 4 中非常快,但在 Hibernate 中非常慢。

谢谢大家!

编辑 2:

分析

编辑 3:

抱歉,这是我添加"DISTINCT"

时的真正问题
SELECT DISTINCT p.* FROM products p INNER JOIN product_store ps ON p.id = ps.product_id
INNER JOIN stores s ON s.id = ps.store_id WHERE s.city = 'Berlin' GROUP BY p.id LIMIT 16 OFFSET 0;

生产

本地

聚合是个大问题。我建议改用 EXISTS

SELECT p.*
FROM products p 
WHERE EXISTS (SELECT 1
              FROM product_store ps INNER JOIN
                   stores s 
                   ON s.id = ps.store_id
              WHERE p.id = ps.product_id AND s.city = 'Berlin' 
             )
LIMIT 16 OFFSET 0;

然后确保您在 product_store(product_id, store_id) 上有索引。我假设您已经在 stores(id) 上建立了索引——因为那应该是主键。

我建议改用 IN,因为选择性谓词在子查询中。如果选择性谓词在父查询中,最好使用 EXISTS。当您使用 IN 时,优化器将子查询写入视图,然后通过唯一索引连接到 products table。请检查同时使用 EXISTSIN 的执行计划以查看差异。

SELECT p.*
FROM products p 
WHERE p.id IN (SELECT ps.product_id
              FROM product_store ps 
              JOIN stores s ON s.id = ps.store_id
              WHERE p.id = ps.product_id AND s.city = 'Berlin' 
             )
LIMIT 16 OFFSET 0;