sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQL:すべてのテーブルフィールドの長さのインデックスを作成します

    テキスト表現で行のサイズを測定するには、行全体をテキストにキャストするだけです。これは、個々の列を連結するよりもはるかに高速です。

    SELECT length(profile::text) FROM profile;
    

    ただし、インデックス内のこの式には3つ(または4つ)の問題があります。

    1. 構文の省略形profile::text CREATE INDEXでは受け入れられません 、標準の構文cast(profile AS text)に括弧を追加するか、デフォルトを設定する必要があります

    2. @jjanesがすでに説明したのと同じ問題IMMUTABLEのみ 関数はインデックス式で許可され、行タイプをtextにキャストできます この要件を満たしていません。偽のIMMUTABLEを作成できます ジェフが概説したようなラッパー関数。

    3. 固有のあいまいさがあります (これはJeffの回答にも当てはまります!):テーブル名と同じ列名がある場合(これは一般的なケースです)、CREATE INDEXで行タイプを参照することはできません。 識別子は常に最初に列名に解決されるためです。

    4. オリジナルとのわずかな違い:これにより、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> 規則であり、多形システム関数の代わりに選択されます。または、別の名前を使用して、関数を多態的にすることもできます...

    関連:



    1. DataReaderからDateTimeフィールドにアクセスするときのMySqlConversionException

    2. MySQLWHERE句の現在の日付

    3. laravelでjoinを使用したサブクエリ

    4. OracleではNUMBERとNUMBER(*、0)は同じですか?