【发布时间】:2020-03-28 21:11:27
【问题描述】:
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 ...)
);
我更改了任何查询中的 where,它们包含很多参数和 CASE,还有不同的 ORDER BY 子句。 这是因为我总是想返回一些东西,但要优先考虑。
我在发出EXPLAIN ANALYZE 时注意到的是,尽管第一个查询实际上返回非空值,但任何查询都会被执行。
我希望引擎只运行第一个查询,如果它返回不为空,则不运行以下查询。
这样我的表现可能会很差。
那么我有什么不好的做法吗?出于性能原因单独运行查询会更好吗?
编辑:
对不起,我没有选择 * 但我只选择了一列。我没有发布我的代码,因为我对我的查询不感兴趣,但这是一个了解引擎如何工作的通用问题。所以我在这里复制了一个非常简单的小提琴http://sqlfiddle.com/#!17/a8aa7/4
我可能错了,但我认为它的行为与我所说的一样:尽管第一个子查询已经返回非空值,但它运行所有子查询
编辑 2:好的,我现在才读到它说从未执行过。所以其他两个查询没有被执行。让我感到困惑的是它们被包含在查询计划中。
无论如何,这对我的问题仍然很重要。出于性能原因单独运行所有查询是否更好?因为看起来即使第一个返回非空值,其他两个子查询也会降低性能
【问题讨论】:
-
你能编辑你的问题并包括你想要达到的目标吗?举例说明您拥有的数据、您希望获得的结果以及您尝试获得结果的思维过程或 SQL。
COALESCE最好像coalesce(new_salary, old_salary, 5000)这样使用,这意味着,如果 new_salary 为空,则使用 old_salary。如果 old_salary 为空,请使用 5000。 -
该查询一开始就不是有效的 SQL。您不能将
coalesce()与select *结合使用。coalesce()适用于单个值,而不适用于表的所有列。如果您退后一步并解释您要解决的潜在问题,您可能会得到更好的答案。请edit您的问题(通过单击其下方的edit 链接)并添加一些示例数据和基于该数据的预期输出为formatted text。请参阅here,了解有关如何创建美观的文本表的一些提示。 -
我认为这不是您的实际代码。所有这些查询都应返回 1 行和 1 列以在 COALESCE 内有效。还要确保 COALESCE 只评估确定结果所需的参数;也就是说,不会从postgresql.org/docs/current/… 评估第一个非空参数右侧的参数。
-
只是为了证明我之前的评论检查这个:dbfiddle.uk/… 运行良好,因为没有评估 coalesce 的第二个参数。如果它被评估,那么查询将失败并出现错误,因为递归 cte 将超过最大迭代次数。
-
@a_horse_with_no_name
标签: sql database postgresql