ホームページ >データベース >mysql チュートリアル >PostgreSQL の `(func()).*` が複数の関数評価を引き起こすのはなぜですか?

PostgreSQL の `(func()).*` が複数の関数評価を引き起こすのはなぜですか?

Linda Hamilton
Linda Hamiltonオリジナル
2025-01-10 11:37:42919ブラウズ

Why Does `(func()).*` in PostgreSQL Cause Multiple Function Evaluations?

*PostgreSQL のパフォーマンスの問題: `(func()).` 構文と冗長な関数呼び出し**

この記事では、複合型または複合セットを返す関数で使用された場合の (func()).* 構文に関連する PostgreSQL のパフォーマンスの問題を検証します。 以下のクエリに示されている元の観察では、予期しない動作が強調表示されています。

<code class="language-sql">SELECT (func(3)).*; -- Leads to multiple function calls</code>

問題: 過剰な関数評価

中心的な問題は、(func()).* が関数の出力の 列に対して個別の関数呼び出しをトリガーすることです。たとえば、4 つの列を返す関数では、予想される 2 つの関数呼び出しではなく、8 つの関数呼び出しが発生する可能性があります。 これは、次のような代替構文とは大きく異なります。

<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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。