たくさんの挿入があるテーブルがあり、フィールド(uploaded_at
)の1つをNULL
に設定します。次に、定期的なタスクがすべてのタプルWHERE uploaded_at IS NULL
を選択し、それらを処理して更新し、uploaded_at
を現在の日付に設定します。
テーブルにインデックスを付けるにはどうすればよいですか?
次のような部分インデックスを使用する必要があることを理解しています。
CREATE INDEX foo ON table (uploaded_at) WHERE uploaded_at IS NULL
またはそのようなsmth。常に混乱しているのですが、常にNULL
であるフィールドにインデックスを付けるのが正しいかどうかです。または、Bツリーインデックスを使用することが正しい場合。ハッシュはより良いアイデアのように見えますが、時代遅れであり、ストリーミングホットスタンバイレプリケーションを介してレプリケートされません。何かアドバイスをいただければ幸いです。
私は次のインデックスで少し実験しました:
"foo_part" btree (uploaded_at) WHERE uploaded_at IS NULL
"foo_part_id" btree (id) WHERE uploaded_at IS NULL
クエリプランナーは常にfoo_part
インデックスを選択するようです。 explain analyse
もfoo_part
インデックスに対して少し良い結果をもたらします。
Index Scan using foo_part on t1 (cost=0.28..297.25 rows=4433 width=16) (actual time=0.025..3.649 rows=4351 loops=1)
Index Cond: (uploaded_at IS NULL)
Total runtime: 4.060 ms
対
Bitmap Heap Scan on t1 (cost=79.15..6722.83 rows=4433 width=16) (actual time=1.032..4.717 rows=4351 loops=1)
Recheck Cond: (uploaded_at IS NULL)
-> Bitmap Index Scan on foo_part_id (cost=0.00..78.04 rows=4433 width=0) (actual time=0.649..0.649 rows=4351 loops=1)
Total runtime: 5.131 ms
この特別なケースでは、実際にインデックスが付けられた列は、当面のクエリとは無関係です。任意の列を選択できます。役に立たない_uploaded_at
_以外のものを選びます。他のクエリに役立つ可能性があり、理想的には8バイト以下の一部の列。
_CREATE INDEX foo ON table bar (some_col) WHERE uploaded_at IS NULL;
_
他の列のユースケースがない場合でも、役に立たない_uploaded_at
_を使用することをお勧めします。そのため、インデックスの追加のメンテナンスコストとH.O.Tの制限を導入しないでください。アップデート。もっと:
または、他のインデックス列を使用しない場合は、constantをインデックス式として使用します。お気に入り:
CREATE INDEX baz ON table bar ((TRUE)) WHERE uploaded_at IS NULL;
括弧が必要です。これにより、インデックスも最小サイズに維持されます。ただし、インデックス列が8バイトを超えることはありませんが(timestamp
の場合)、それでもやはり最小サイズです。関連: