首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >简单的查询非常慢

简单的查询非常慢
EN

Stack Overflow用户
提问于 2020-03-16 21:02:21
回答 2查看 80关注 0票数 2

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

代码语言:javascript
运行
复制
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;

这些数字如下:

代码语言:javascript
运行
复制
SELECT count(*) FROM products;

43309

代码语言:javascript
运行
复制
SELECT count(*) FROM product_store;

1456445

代码语言:javascript
运行
复制
SELECT count(*) FROM stores;

155

我想它可以用于关系表,但是36秒对于16行来说太多了。

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

编辑:

无论出于什么原因,问题不是Postgres造成的,而是Hibernate造成的。查询在pgAdmin 4中相当快,但在Hibernate中却非常慢。

谢谢大家!

编辑2:

分析

编辑3:

抱歉,这是我添加"DISTINCT“时真正的问题所在

代码语言:javascript
运行
复制
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;

生产

本地

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-16 21:16:31

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

代码语言:javascript
运行
复制
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)上有了一个索引--因为它应该是主键。

票数 3
EN

Stack Overflow用户

发布于 2020-03-16 21:55:15

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

代码语言:javascript
运行
复制
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;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60706521

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档