我有一个查询,它需要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
我想它可以用于关系表,但是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;
生产
本地
发布于 2020-03-16 21:16:31
聚合是一个大问题。我建议改用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)
上有了一个索引--因为它应该是主键。
发布于 2020-03-16 21:55:15
我建议使用IN
,因为选择性谓词在子查询中。如果选择性谓词在父查询中,最好使用EXISTS
。当您使用IN
时,优化器将子查询写入视图,然后通过唯一索引连接到products
表。请查看同时使用EXISTS
和IN
的执行计划,了解差异。
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;
https://stackoverflow.com/questions/60706521
复制相似问题