ホームページ >データベース >mysql チュートリアル >PostgreSQL の `(func()).*` が複数の関数評価を引き起こすのはなぜですか?
*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 サイトの他の関連記事を参照してください。