sql - Postgres执行合并中的所有子查询
问题描述
Postgres 中的 COALESCE 是一个返回第一个参数不为空的函数。所以我在子查询中使用了合并,例如:
SELECT COALESCE (
( SELECT * FROM users WHERE... ORDER BY ...),
( SELECT * FROM users WHERE... ORDER BY ...),
( SELECT * FROM users WHERE... ORDER BY ...),
( SELECT * FROM users WHERE... ORDER BY ...)
);
我更改了任何查询中的位置,它们包含许多参数和 CASE,还有不同的 ORDER BY 子句。这是因为我总是想返回一些东西,但要优先考虑。
我在发布时注意到EXPLAIN ANALYZE
的是,尽管第一个查询实际上返回了 NOT 空值,但仍会执行任何查询。我希望引擎只运行第一个查询,如果它返回不为空,则不运行以下查询。
这样我的表现可能会很差。
那么我是否在做任何不好的做法,出于性能原因单独运行查询会更好吗?
编辑:
对不起,我没有选择 * 但我只选择了一列。我没有发布我的代码,因为我对我的查询不感兴趣,但这是一个了解引擎如何工作的通用问题。所以我在这里重现了一个非常简单的小提琴http://sqlfiddle.com/#!17/a8aa7/4
我可能错了,但我认为它的行为与我所说的一样:尽管第一个子查询已经返回非空值,但它运行所有子查询
编辑2:好的,我现在才读到它说从未执行过。所以其他两个查询没有被执行。让我感到困惑的是它们被包含在查询计划中。
无论如何,这对我的问题仍然很重要。出于性能原因单独运行所有查询是否更好?因为看起来即使第一个返回非空值,其他两个子查询也会降低性能
解决方案
对于单独的SELECT
查询,我建议使用UNION ALL
/LIMIT 1
代替。根据您的小提琴:
(select user_id from users order by age limit 1) -- misleading example, see below
UNION ALL
(select user_id from users where user_id=1)
UNION ALL
(select user_id from users order by user_id DESC limit 1)
LIMIT 1;
db<>在这里摆弄
出于三个原因:
适用于任何
SELECT
列表:单个表达式(您的小提琴)、多个或整行(您在问题中的示例)。您可以将实际
NULL
值与“无行”区分开来。由于user_id
PK 在示例中(因此,NOT NULL
),因此问题不会在示例中出现。NULL
但是对于可以是,COALESCE
不能区分两者的表达式,“无行”被强制NULL
用于查询目的。看:快点。
除此之外,您SELECT
在示例中的第一个使这成为了一场疯狂的追逐。如果至少有一行,则返回一行。在这种情况下,剩下的就是噪音。
有关的:
推荐阅读
- sql-server - SSDT Schema Compare 总是添加对象,在解决方案中是“Build = None”
- crash - mariadb 经常崩溃
- angular - 如何根据角度条件显示不同的模板
- oracle-apex - 如何通过 ATP 将 oracle apex 应用程序文件保存到对象存储?
- angular - 此页面上的代码禁用了 Internet Explorer Angular 2 中的前后缓存
- java - Java中String方法中的类型转换equals
- asp.net - 在asp.net c#中的数据库中显示网页中的Word和excel文件
- php - GoDaddy API - 批量域查询 php
- bootstrap-4 - 在移动视图上删除容器
- python-3.x - 在 numpy.reshape 中获取太多数组错误的索引