テキスト表現で行のサイズを測定するには、行全体をテキストにキャストするだけです。これは、個々の列を連結するよりもはるかに高速です。
SELECT length(profile::text) FROM profile;
ただし、インデックス内のこの式には3つ(または4つ)の問題があります。
-
構文の省略形
profile::text
CREATE INDEX
では受け入れられません 、標準の構文cast(profile AS text)
に括弧を追加するか、デフォルトを設定する必要があります -
@jjanesがすでに説明したのと同じ問題 :
IMMUTABLE
のみ 関数はインデックス式で許可され、行タイプをtext
にキャストできます この要件を満たしていません。偽のIMMUTABLE
を作成できます ジェフが概説したようなラッパー関数。 -
固有のあいまいさがあります (これはJeffの回答にも当てはまります!):テーブル名と同じ列名がある場合(これは一般的なケースです)、
CREATE INDEX
で行タイプを参照することはできません。 識別子は常に最初に列名に解決されるためです。 -
オリジナルとのわずかな違い:これにより、
text
に列区切り文字、行デコレータ、場合によってはエスケープ文字が追加されます。 表現。ユースケースにはあまり関係ありません。
ただし 、行のサイズの大まかな指標として、より根本的な代替案を提案します: pg_column_size()
。さらに短く、高速になり、問題を回避します 1 、 3 および4 :
SELECT pg_column_size(profile) FROM profile;
発行2 ただし、残ります:pg_column_size()
STABLE
のみです 。シンプルで安価なSQLラッパー関数を作成できます:
CREATE OR REPLACE FUNCTION pg_column_size(profile)
RETURNS int LANGUAGE sql IMMUTABLE AS
'SELECT pg_catalog.pg_column_size($1)';
次に、@jjanesの概要のように進みます。詳細:
行タイプprofile
で関数を作成したことに注意してください パラメータとして。 Postgresでは関数のオーバーロードが許可されているため、同じ関数名を使用できます。ここで、一致する行タイプをpg_column_size()
にフィードすると 関数の型の解決<に従って、カスタム関数はより厳密に一致します。 / a> 規則であり、多形システム関数の代わりに選択されます。または、別の名前を使用して、関数を多態的にすることもできます...
関連: