6

在 Postgres 数据库中,我需要过滤表 A 中的一组数十万行,方法是仅包含行中 IP 地址列(inet 类型)与数千个 IP 地址块(类型cidr)在另一个表B中。我已经尝试了第一个表中inet地址和第二个表中的cidr范围的各种索引,但无论我做什么,规划器都会进行嵌套顺序扫描,将<<运算符应用于每对 IP 地址和前缀。

有没有办法通过索引或其他巧妙的技巧来加快速度?(我可以求助于外部程序脚本,但我想知道它在 Postgres 中是否可行。)

谢谢!

4

3 回答 3

9

这是一个古老的问题,但在谷歌搜索结果中很突出,所以在这里发布我的 2 美分:

使用 Postgres 9.4 及更高版本,您可以将 GIST 索引用于 inet 和 cidr:https ://www.postgresql.org/docs/current/static/gist-builtin-opclasses.html

例如,以下查询将使用 gist 索引(假设来自 MaxMind 的免费数据集的表):

create index on geolite2_city_ipv4_block using gist (network inet_ops);

select * from geolite2_city_ipv4_block where network >>= '8.8.8.8';
于 2016-10-17T15:21:37.233 回答
2

结案。为了加快速度,请执行以下操作:

鉴于上述情况,如果您对所有比较地址使用类型 ip4(假设您正在处理 v4 地址),那么规划器将利用这些列上的索引。

谢谢你们的帮助,伙计们!

于 2013-09-12T00:20:19.070 回答
2

你看过ip4r吗? http://pgfoundry.org/projects/ip4r。IIRC,对于与 INET 相关的查找,它真的很快。

于 2013-09-11T23:38:50.230 回答