Postgresql或具有空子查询的条件

Postgresql或具有空子查询的条件,postgresql,Postgresql,我如何优化WHERE条件包括检查user\u id=X或user\u id IN(某些可能不返回结果的子查询)的查询 在我下面的示例中,查询1和查询2都非常快(

我如何优化WHERE条件包括检查user\u id=X或user\u id IN(某些可能不返回结果的子查询)的查询

在我下面的示例中,查询1和查询2都非常快(<1毫秒),但查询3(它只是查询1和查询2中条件的OR)要慢得多(50毫秒)

有人能解释一下为什么查询3这么慢吗?一般来说,我应该采用什么类型的查询优化策略来避免这个问题?我意识到我的示例中的子查询可以很容易地消除,但在现实生活中,有时子查询似乎是获取所需数据的最简单的方式

相关代码和数据:

发布数据

用户数据

拆分查询(已编辑):

拆分查询(已编辑):


此特定查询中的大多数时间与索引扫描相关。下面是一个从不同角度进行的查询,以避免出现这种情况,但应该返回相同的结果

SELECT posts.* FROM users JOIN posts on posts.created_by_id=users.id WHERE users.id=123 or login='nobodyhasthislogin'
这将从用户表中进行选择,执行一次筛选,然后将帖子连接到该表中


我意识到问题是关于优化的技巧,而不是这个具体的查询。为了回答这个问题,我的建议是运行
EXPLAIN ANALYZE
并阅读解释结果,-答案对我很有帮助。

在这个特定查询中,大部分时间与索引扫描相关。下面是一个从不同角度进行的查询,以避免出现这种情况,但应该返回相同的结果

SELECT posts.* FROM users JOIN posts on posts.created_by_id=users.id WHERE users.id=123 or login='nobodyhasthislogin'
这将从用户表中进行选择,执行一次筛选,然后将帖子连接到该表中

我意识到问题是关于优化的技巧,而不是这个具体的查询。为了回答这个问题,我的建议是运行
EXPLAIN ANALYZE
并阅读解释结果,-答案对我很有帮助。

怎么样:

EXPLAIN ANALYZE
SELECT  * 
FROM    posts
WHERE   created_by_id IN (
           SELECT 123
           UNION ALL
           SELECT id FROM
           users  WHERE
           login  = 'nobodyhasthislogin') LIMIT 100;
那么:

EXPLAIN ANALYZE
SELECT  * 
FROM    posts
WHERE   created_by_id IN (
           SELECT 123
           UNION ALL
           SELECT id FROM
           users  WHERE
           login  = 'nobodyhasthislogin') LIMIT 100;

为什么运行解释分析,然后不提供信息?还有,有什么理由不只是执行联接吗?查询1和查询2在不到1毫秒的时间内返回,查询3需要50毫秒。我没有包括查询计划,因为这些计划需要大量文本,但您可以使用提供的数据/代码完全复制我的示例1)导入后是否运行了“真空分析”?统计数据对乐观主义者/规划者有很大帮助。2) 在(几乎)所有情况下,
都存在(…)
基本上优于(…)中的
,因为它可以避免排序传递/删除重复项。3) 检查/向我们展示计划(只需在实际查询前放置
explain analyze
),为什么运行explain analyze,然后不提供信息?还有,有什么理由不只是执行联接吗?查询1和查询2在不到1毫秒的时间内返回,查询3需要50毫秒。我没有包括查询计划,因为这些计划需要大量文本,但您可以使用提供的数据/代码完全复制我的示例1)导入后是否运行了“真空分析”?统计数据对乐观主义者/规划者有很大帮助。2) 在(几乎)所有情况下,
都存在(…)
基本上优于(…)
中的
,因为它可以避免排序传递/删除重复项。3) 检查/向我们展示计划(只需在实际查询前放置
explain analyze
)此查询生成与查询3相同的结果,但更改我的答案的速度与查询3相同(50毫秒),希望此帮助此查询生成与查询3相同的结果,但更改我的答案的速度与查询3相同(50毫秒),希望这有助于Spostgres对主查询中找到的每个记录执行一次不相关的子查询?我没有仔细阅读查询计划。看起来原始查询涉及的大部分时间都与posts_pkey的索引扫描有关。我对我的帖子进行了编辑以反映这一点,但稍后我将对此进行更详细的研究。Postgres对主查询中找到的每个记录执行一次不相关的子查询?我没有仔细阅读查询计划。看起来原始查询涉及的大部分时间都与posts_pkey的索引扫描有关。我已经编辑了我的帖子来反映这一点,但稍后我将对其进行更详细的研究。
in()
并不是最有效的解决方案。另一个缺点是排序方法:快速排序内存:17kB。我们怎么看不到最简单的一个-
JOIN
Scott S
的答案似乎是可行的,只要在
created\u by\u id
列中没有
NULL
值。你能解释为什么in在Postgres中无效吗?我来自Oracle的背景,可能会将其转换为散列连接,而同样的转换似乎也发生在Postgres 9.1中。我观察到的不同之处在于,子查询结果往往被用作哈希表,如果子查询数据集较大,则可能导致效率低下。但在我看来,除非我遗漏了什么,否则它本身并没有问题?
IN()
不是最有效的解决方案。另一个缺点是排序方法:快速排序内存:17kB。我们怎么看不到最简单的一个-
JOIN
Scott S
的答案似乎是可行的,只要在
created\u by\u id
列中没有
NULL
值。你能解释为什么in在Postgres中无效吗?我来自Oracle的背景,可能会将其转换为散列连接,而同样的转换似乎也发生在Postgres 9.1中。我观察到的不同之处在于,子查询结果往往被用作哈希表,如果子查询数据集较大,则可能导致效率低下。但在我看来,这个问题本身并不成问题,除非我遗漏了什么?