Postgresql或具有空子查询的条件
我如何优化WHERE条件包括检查user\u id=X或user\u id IN(某些可能不返回结果的子查询)的查询 在我下面的示例中,查询1和查询2都非常快(<1毫秒),但查询3(它只是查询1和查询2中条件的OR)要慢得多(50毫秒) 有人能解释一下为什么查询3这么慢吗?一般来说,我应该采用什么类型的查询优化策略来避免这个问题?我意识到我的示例中的子查询可以很容易地消除,但在现实生活中,有时子查询似乎是获取所需数据的最简单的方式 相关代码和数据: 发布数据 用户数据 拆分查询(已编辑): 拆分查询(已编辑):Postgresql或具有空子查询的条件,postgresql,Postgresql,我如何优化WHERE条件包括检查user\u id=X或user\u id IN(某些可能不返回结果的子查询)的查询 在我下面的示例中,查询1和查询2都非常快(
此特定查询中的大多数时间与索引扫描相关。下面是一个从不同角度进行的查询,以避免出现这种情况,但应该返回相同的结果
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中。我观察到的不同之处在于,子查询结果往往被用作哈希表,如果子查询数据集较大,则可能导致效率低下。但在我看来,这个问题本身并不成问题,除非我遗漏了什么?