ホームページ > データベース > mysql チュートリアル > PostgreSQL で `(func()).*` を使用するときに複数の関数評価を回避するにはどうすればよいですか?

PostgreSQL で `(func()).*` を使用するときに複数の関数評価を回避するにはどうすればよいですか?

DDD
リリース: 2025-01-10 11:19:42
オリジナル
408 人が閲覧しました

How Can I Avoid Multiple Function Evaluations When Using `(func()).*` in PostgreSQL?

*関数呼び出しが繰り返される原因となる PostgreSQL での `(func()).` の使用は避けてください**

PostgreSQL では、(func()).* 構文を使用してテーブルまたは複合型を返す関数の結果にアクセスすると、列ごとに関数が繰り返し呼び出される可能性があります。これは、特に関数の計算コストが高い場合、パフォーマンスに影響を与える可能性があります。

解決策

この問題を回避するには、次のように関数呼び出しをサブクエリでラップします。

<code class="language-sql">SELECT (mf).* FROM (
    SELECT my_func(x) AS mf FROM some_table
) sub;</code>
ログイン後にコピー
ログイン後にコピー

これにより、結果に含まれる列の数に関係なく、関数が 1 回だけ呼び出されることが保証されます。あるいは、PostgreSQL 9.3 以降では、LATERAL JOIN 構文を使用できます:

<code class="language-sql">SELECT mf.*
FROM some_table
LEFT JOIN LATERAL my_func(some_table.x) AS mf ON true;</code>
ログイン後にコピー

問題の原因

への重複した呼び出しが発生するのは、パーサーが (func()).* を列名のリストのプレースホルダーとして扱うためです。式マクロが一連の個別の列に展開されるため、関数が複数回呼び出されます。

デモ

問題と解決策を示すために、関数を作成します:

<code class="language-sql">CREATE OR REPLACE FUNCTION my_func(integer)
RETURNS TABLE(a integer, b integer, c integer) AS $$
BEGIN
    RAISE NOTICE 'my_func(%)',;
    RETURN QUERY SELECT , , ;
END;
$$ LANGUAGE plpgsql;</code>
ログイン後にコピー

とダミーデータを含むテーブル:

<code class="language-sql">CREATE TABLE some_table AS SELECT x FROM generate_series(1,10) x;</code>
ログイン後にコピー

次のクエリの結果を比較します:

  • 元の構文:
<code class="language-sql">SELECT (my_func(x)).* FROM some_table;</code>
ログイン後にコピー
  • 解決策の構文:
<code class="language-sql">SELECT (mf).* FROM (
    SELECT my_func(x) AS mf FROM some_table
) sub;</code>
ログイン後にコピー
ログイン後にコピー

元の構文では複数の通知が生成されるのに対し、ソリューション構文では 1 つの通知のみが生成され、複数の関数呼び出しを回避する効果が示されていることがわかります。

以上がPostgreSQL で `(func()).*` を使用するときに複数の関数評価を回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート