IP 地理定位查询太慢

IP geolocating query too slow

我最近开始在工作中使用 PostgreSQL,并且正在尝试优化查询以根据用户的 IP 地址对用户进行地理定位。我不完全确定如何读取解释分析的输出。自上次更新以来所有表都已清理,所以我知道这不是缓慢的原因。

我有以下表格:

session_ipaddress:
存储访问者的 IP 地址,它有大约 250,000 行。相关列和索引:

session_id VARCHAR PRIMARY KEY,
ip_address INET,
ip_int BIGINT

BTREE INDEX on ip_int

ipblocks_201601:
http://dev.maxmind.com/geoip/geoip2/geolite2/ 获得的 MaxMind GeoLite2 City Blocks 数据库有两个额外的列 min_ipmax_ip,它们一起保存 CIDR 块中的 IP 地址范围。相关的列和索引是:

network CIDR PRIMARY KEY,
geoname_id INTEGER,
min_ip BIGINT,
max_ip BIGINT

BTREE INDEX ON geoname_id
BTREE INDEX ON min_ip
BTREE INDEX ON max_ip

ipgeolookup_201601:
en 语言环境的 GeoLite2 位置数据库。相关列和索引:

geoname_id INTEGER PRIMARY KEY,
country_name VARCHAR,
subdivision_1_name VARCHAR,
city_name VARCHAR

BTREE INDEX ON country_name
BTREE INDEX ON subdivision_1_name
BTREE INDEX ON city_name

这是我的查询 运行,需要大约 20 秒才能完成。

SELECT
  geo.country_name
, geo.subdivision_1_name region_name
, geo.city_name
, COUNT(s.session_id) location_unresolved
FROM session_ipaddress s
JOIN ipblocks_201601 ip ON ip.min_ip <= s.ip_int AND ip.max_ip >= s.ip_int
JOIN ipgeolookup_201601 geo ON geo.geoname_id = ip.geoname_id
WHERE geo.country_name = 'United States' OR geo.country_name = 'Canada'
GROUP BY 1, 2, 3;

总运行时间:22192.814 毫秒,这是 EXPLAIN ANALYZE 的输出:http://explain.depesz.com/s/DNcV

您应该尝试添加复合索引。

一个 ipblocks_201601 包括 (geoname_id, min_ip, max_ip)

另一个 ipgeolookup_201601 包括 (country_name, geoname_id)

OP 编辑​​:

最大的改进来源是 work_mem 从默认的 1MB 增加到 4MB。数据库在一台有 2GB 内存的机器上。
执行时间从 20 秒下降到 5 秒

添加复合索引进一步缩短了执行时间。