我在Postgres优化中的特定情况下遇到了很多麻烦。
基本上,我有三个表,它们将简化为:
Place
:id,名称(字符串(,选择(布尔值(Bookmark
:id、用户(整数(、地点(整数(User
: id, name (字符串(
Place
表有几百万行(并且还在增长(,但其中相对较少的行select
为真。
我在这些表上有几个索引,显然在所有id
上,加上一个关于place where "select"=true
的部分索引,以及一个关于bookmark
(用户、地点(组合的唯一索引。还有更多,但我认为它们在这里无关紧要。
当我执行以下类型的查询时:
SELECT *
FROM place
WHERE "select"
LIMIT 10;
需要 3 毫秒。
当我执行以下类型的查询时:
SELECT *
FROM place
WHERE exists (SELECT id
FROM bookmark
WHERE user IN (1,2,3,4)
AND bookmark.place = place.id)
LIMIT 10;
它的速度也非常快。
但是,如果我在这两种情况下都做OR
,如下所示:
SELECT *
FROM place
WHERE "select"
OR exists (SELECT id
FROM bookmark
WHERE user IN (1,2,3,4)
AND bookmark.place = place.id)
LIMIT 10;
它减慢到1秒以上。
除了在我的代码中执行两个查询并组合结果之外,还有什么方法可以优化它吗?
老问题,OR
是一个性能杀手。
使用UNION
:
(SELECT * FROM place
WHERE select
LIMIT 10)
UNION
(SELECT * FROM place
WHERE exists (SELECT 1 FROM bookmark
WHERE user IN (1,2,3,4)
AND bookmark.place = place.id)
LIMIT 10)
LIMIT 10;