*PostgreSQL 性能问题:`(func()).` 语法和冗余函数调用**
本文研究了 PostgreSQL 中与返回复合类型或集合的函数一起使用时与 (func()).*
语法相关的性能问题。 下面的查询中显示的原始观察结果突出显示了意外行为:
<code class="language-sql">SELECT (func(3)).*; -- Leads to multiple function calls</code>
问题:过度的功能评估
核心问题是 (func()).*
触发对函数输出中的 每个 列的单独函数调用。例如,返回四列的函数可能会导致八次函数调用,而不是预期的两次。 这与替代语法形成鲜明对比,例如:
<code class="language-sql">SELECT N, func(N); -- More efficient approach</code>
解决方案:高效查询重写
为了避免过多的调用,子查询提供了一种解决方法。 虽然通常有效,但这并不是一个完美的解决方案,并且可能会引入其他性能考虑因素。
对于 PostgreSQL 9.3 及更高版本,LATERAL
关键字提供了更好的解决方案:
<code class="language-sql">SELECT mf.* FROM some_table LEFT JOIN LATERAL my_func(some_table.x) AS mf ON true;</code>
根本原因:PostgreSQL 解析器行为
根本原因在于 PostgreSQL 的解析器如何处理 *
构造中的 (func()).*
通配符。 解析过程中通配符扩展到各个列是冗余函数调用的根源。
性能基准和演示
自定义函数示例演示了有问题的语法与建议的解决方法之间的性能差异。 测试表明子查询方法(或 CTE)提供了显着的性能改进。
结论:优化 PostgreSQL 中的查询
虽然 (func()).*
的多函数调用问题仍然是已知行为,但解决方法,特别是使用 LATERAL
(PostgreSQL 9.3),为开发人员提供了优化查询性能并减少不必要的函数评估的有效策略。
以上是为什么 PostgreSQL 中的 `(func()).*` 会导致多次函数求值?的详细内容。更多信息请关注PHP中文网其他相关文章!