私は PostgreSQL 9.2 を使用しており、IP 範囲の表があります。SQLは次のとおりです。
CREATE TABLE ips (
id serial NOT NULL,
begin_ip_num bigint,
end_ip_num bigint,
country_name character varying(255),
CONSTRAINT ips_pkey PRIMARY KEY (id )
)
begin_ip_num
と の両方に単純な B ツリー インデックスを追加しましたend_ip_num
。
CREATE INDEX index_ips_on_begin_ip_num ON ips (begin_ip_num);
CREATE INDEX index_ips_on_end_ip_num ON ips (end_ip_num );
使用されているクエリは次のとおりです。
SELECT ips.* FROM ips
WHERE 3065106743 BETWEEN begin_ip_num AND end_ip_num;
問題は、BETWEEN
クエリが のインデックスのみを使用していることbegin_ip_num
です。インデックスを使用した後、 を使用して結果をフィルタリングしend_ip_num
ます。EXPLAIN ANALYZE
結果は次のとおりです。
Index Scan using index_ips_on_begin_ip_num on ips (cost=0.00..2173.83 rows=27136 width=76) (actual time=16.349..16.350 rows=1 loops=1)
Index Cond: (3065106743::bigint >= begin_ip_num)
Filter: (3065106743::bigint <= end_ip_num)
Rows Removed by Filter: 47596
Total runtime: 16.425 ms
begin_ip_num
と の両方に複合インデックスを追加するなど、インデックスのさまざまな組み合わせを既に試しましたend_ip_num
。