2017-01-05 7 views
4

私は、多くのエントリを持つテーブルと長さが8の異なるステータスを持つvarcharフィールドを持っています。ステータスは「STATUS1」、「STATUS2」、...とほとんどの場合、NULLになっています。PostgreSQL - ステータスフィールドの正しいインデックス選択(varchar)

フィールドにインデックスを付けると、等しい値が多く、ポストグルでインデックスが使用されないため、フィールドのインデックス化はあまり行われません。

私の質問です:このようなフィールドのインデックスを作成し、より速くする方法はありますか?ほとんどの場合、私はstatus IS NULLを照会しています。私はそれをもっと速くすることはできません。しかし、status = 'STATUS1'を確認するとどうなりますか?

+1

パフォーマンスが問題になる場合は、ここでvarcharsではなく整数を使用することを検討する必要があります。ステータス名が重要な場合は、常に整数からステータス名への関連付けを含むサテライト関係を作成できます。 –

+0

これは、 'statusがnullの行数 'が結果から削除される行の数に依存します。その条件によって少数の行しか返されない場合、Postgres **はstatusカラムのインデックスを使用します。それがすべての行の大部分であれば、インデックスは本当に助けにならないでしょう(しかし部分的なインデックスを作ることは試してみる価値があります) –

+0

私はそれも心に留めていましたが、私はむしろVarcharフィールドを維持したいと思います。パフォーマンスはこの時点では重要ではありませんが、私は完全に欠場する共通の方法があるかどうかを知りたがっています。 – Andwari

答えて

2

場合によってはpartial indexesを使用できます。あなたは、あなたがpartial indexを作成する場合は、このクエリはおそらく速く(多くの)を実行します

SELECT * 
    FROM the_table 
WHERE color in ('green', 'blue') AND status = 'STATUS1' ; 

に類似したクエリをたくさん持っているとしましょう:

CREATE TABLE the_table 
(
    color text, 
    status character varying(8) 
    /* and anything you need */ 
) ; 

CREATE INDEX 
    ON public.the_table (color) 
    WHERE status = 'STATUS1' ; 

のPostgreSQLを使用している場合(それを可能にする任意の他のデータベースoを)、私はおそらくenumerated typeを作成するだろう、代わりにvarchar。 (8)のみ列挙値が許可されます(そう「autochecking」)、および情報(およびインデックスそれ)を格納するために必要なスペースvarchar型よりも小さい::次の2つの利点があり、その後

CREATE TYPE status_type AS ENUM 
    ('STATUS1', 
    'STATUS2', 
    'STATUS3'); 

と作成しますそれを持つテーブル:

CREATE TABLE the_table 
(
    color text, 
    status status_type 
    /* and anything you need */ 
) ; 

あなたは、列挙のために許可された値(例えば、メニューを作成する)、check hereである(プログラム的に)知っておく必要がある場合。

データベースで列挙できない場合は、(anonymous_id_PK、status_value)の小さな[ish]テーブルに正規化します。

+1

私はこれが最良の解決策であると思います。 Enumsについても検討します。ありがとうございました! – Andwari

関連する問題