首页 > 数据库 > mysql教程 > 在 SQL 查询中使用 `(func()).*` 时如何防止多个函数调用?

在 SQL 查询中使用 `(func()).*` 时如何防止多个函数调用?

Linda Hamilton
发布: 2025-01-10 11:51:42
原创
589 人浏览过

How to Prevent Multiple Function Calls When Using `(func()).*` in SQL Queries?

在 SQL 查询中使用 (func()).* 避免重复函数调用

当使用返回表或复合类型的函数时,(func(arg)).* 语法可能会导致每个输出列的冗余函数调用。 在表或子查询中调用函数时会出现此问题,其中 (func()).* 通常是唯一实用的方法。

问题

意外的是,(func()).* 触发了多个函数执行——数量等于输出列数。 例如,返回四列的函数可能会被调用八次,而不是预期的两次。

解决方案

要纠正此问题,请将函数调用封装在子查询中:

SELECT (mf).* FROM (
    SELECT my_func(x) AS mf FROM some_table
) sub;
登录后复制

这通常可以避免额外的函数调用,并且不会引入额外的运行时扫描。 为了绝对确定,请考虑 OFFSET 0 技巧或利用 PostgreSQL 在 CTE 优化方面的限制:

SELECT (mf).* FROM (
    SELECT my_func(x) AS mf FROM some_table OFFSET 0
) sub;

WITH tmp(mf) AS (
    SELECT my_func(x) FROM some_table
)
SELECT (mf).* FROM tmp;
登录后复制

PostgreSQL 9.3 及更高版本提供了更优雅的解决方案,使用 LATERAL:

SELECT mf.*
FROM some_table
LEFT JOIN LATERAL my_func(some_table.x) AS mf ON true;
登录后复制

根本原因

解析器将 (func()).* 扩展为列列表是根本原因。 解析后的树显示 (func(x)).* 转换为:

<code>(my_func(x)).i, (my_func(x)).j, (my_func(x)).k, (my_func(x)).l</code>
登录后复制

这种低效的节点克隆,而不是单个函数调用节点复制,导致了重复调用。

以上是在 SQL 查询中使用 `(func()).*` 时如何防止多个函数调用?的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板