複数列のインデックスを試してください。ただし、2番目の列の順序を逆にしてください:
CREATE INDEX index_ips_begin_end_ip_num ON ips (begin_ip_num, end_ip_num DESC);
単一列のインデックスは、ほぼ同じ速度で逆方向にスキャンできるため、順序付けはほとんど関係ありません。ただし、複数列のインデックスでは重要です。
私が提案するインデックスを使用すると、Postgresは最初の列をスキャンして、インデックスの残りの部分が最初の条件を満たすアドレスを見つけることができます。次に、最初の列の値ごとに、最初の列が失敗するまで、2番目の条件を満たすすべての行を返すことができます。次に、最初の列の次の値などにジャンプします。
これはまだあまり効率的ではありません Postgresは、最初のインデックス列をスキャンして2番目のインデックス列をフィルタリングするだけの方が高速な場合があります。データの分布に大きく依存します。
いずれにせよ、CLUSTER
上記の複数列のインデックスを使用してできます ヘルプパフォーマンス:
CLUSTER ips USING index_ips_begin_end_ip_num
このようにして、最初の条件を満たす候補は、同じまたは隣接するデータページにパックされます。最初の列の値ごとに多くの行がある場合は、パフォーマンスを大幅に向上させることができます。それ以外の場合はほとんど効果がありません。
(目的のための非ブロッキング外部ツールもあります:pg_repackまたはpg_squeeze。)
また、autovacuumが実行され、適切に構成されていますか、またはANALYZE
を実行していますか テーブルの上?適切なクエリプランを選択するには、Postgresの現在の統計が必要です。
ここで本当に役立つのは、GiSTインデックスです。 int8range
の場合 PostgreSQL9.2以降で使用可能な列。
さらに読む:
- タイムスタンプの範囲(2列)でクエリを最適化する
もし IP範囲は、組み込みのネットワークタイプinet
のいずれかでカバーできます。 またはcidr
、2つのbigint
を置き換えることを検討してください 列。または、さらに良いことに、追加モジュール ip4r を見てください Andrew Gierthによる(標準分布にはありません。それに応じてインデックス作成戦略が変更されます。
それを除けば、部分インデックスを備えた洗練されたレジームを使用して、dba.SEでこの関連する回答を確認できます。高度な機能ですが、優れたパフォーマンスを提供します:
- 空間インデックスは「範囲-順序-制限」クエリに役立ちますか