首頁 > 資料庫 > mysql教程 > 在 SQL 查詢中使用 `(func()).*` 時如何防止多個函數呼叫?

在 SQL 查詢中使用 `(func()).*` 時如何防止多個函數呼叫?

Linda Hamilton
發布: 2025-01-10 11:51:42
原創
587 人瀏覽過

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
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板