【发布时间】:2016-02-22 15:31:26
【问题描述】:
我最近开始在工作中使用 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:
MaxMind GeoLite2 City Blocks 数据库从http://dev.maxmind.com/geoip/geoip2/geolite2/ 获得,另外两个列min_ip 和max_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
【问题讨论】:
-
您确定您的
explain analyze与此查询匹配吗?因为有一个按contry_name排序,而您的查询没有这种排序。 -
是的,我确信解释分析是针对这个查询的。我不确定它为什么需要排序,我认为它与聚合有关。它还对
city_name和subdivision_1_name字段进行排序。 -
为什么是最小/最大 ip?你就不能
network >> ip_address吗? -
network >> ip_address甚至更慢且不使用索引。不知道为什么,但是将范围提取到单独的列中并转换为整数,将速度提升到当前级别。
标签: postgresql ip-address postgresql-9.3 maxmind