ruby-on-rails - postgres 在 2 db 列之间找到 IP 地址
问题描述
我有一个 IP 地址表。该表有两列名称starting_ip
和ending_ip
。该表如下所示:
现在,假设我有一个随机 IP 地址。从那个随机的 IP 地址,我想知道city_name
. 这意味着我需要知道随机 IP 地址位于哪个范围之间,基于starting_ip
和ending_ip
。然后找到 1 条记录并获取city_name
.
我写了一个这样的查询:
class IpToCity < ActiveRecord::Base
establish_connection :"ip_database_#{Rails.env}"
scope :search_within_ip_range, -> (ip_address) do
self.connection.select_all("
with candidate as (
select * from ip_cities
where ending_ip >= '#{ip_address}'::inet
order by ending_ip asc
limit 1
)
select * from candidate
where starting_ip <= '#{ip_address}'::inet;
")
end
end
这是一个范围,我通过随机 IP 并获得一条记录。问题是,查询工作正常,但速度很慢。任何建议,如何使它更快?
提前致谢!
解决方案
所有行都符合这种格式吗?
starting_ip ending_ip
x.y.z.0 x.y.z.255
如果是这样,那么您可以为“前缀”添加另一列:xyz
然后将目标的前 3 个八位字节与前缀列进行匹配。
更新数据库时,将跨越多个前缀的行分成多行。
最大行数为 16.8M (256 3 ),它很小,仅比您当前的 5M 略大。
推荐阅读
- python - 寻找有关构建从通用文件解析器派生的 XML 解析器的技巧
- ios - dyld:库未加载:@rpath .. 原因:找不到图像
- google-sheets - 使用 Javascript 在 Google 电子表格中插入日期 (yyyy-MM-dd HH:mm:ss) 添加撇号
- javascript - 带有串口本机模块的电子
- javascript - 如果用户当前的时区时间与“开放时间”(ES6)一致,则显示 div
- r - 删除 R Leaflet 中的特定图层
- r - 如果在公式参数中使用点,为什么 r 聚合求和会产生错误的结果?
- python - Python asyncio NotImplementedError
- excel - 如何从数据透视表中过滤出所有“字符串”
- javascript - JavaScript API fetch 在第一次加载时不起作用