ip2location查询一百万条记录

时间:2013-07-12 09:39:48

标签: database perl

我订阅了ip2location服务,它以这种格式提供了一个SQL表

FromIP (int), ToIP(int), lat, long, city  etc etc 

我想解析访问日志并对所有用户进行分类 访问日志具有IP地址和用户ID(比如说)

所以我运行像

这样的查询
select city from ip2location where FromIP <= $ipAsInt  AND ToIP => $ipAsInt

但这需要花费很长时间才能完成我需要解析的百万条记录。我想这必须是ip2location的一个非常常见的用法。是否可以优化结构?

5 个答案:

答案 0 :(得分:2)

你也可以写这样的查询

select city,ToIP from ip2location where ToIP >= $ipAsInt order by ToIP limit 1

这将比以前快得多。

此外,您可以索引ToIP列以提高性能。

正如ip2location建议的那样,您可以使用

创建FromIP和ToIP的复合主键
ALTER TABLE ip2location ADD PRIMARY KEY(FromIP,ToIP);

答案 1 :(得分:1)

确保您的表格已在FromIPToIP上编入索引。 检查数据库,是否具有完整的内存表中的查找功能。

您可能希望将所有IP加载到另一个表中,并在单个SQL语句中将城市加入此表,而不是为您获得的每个IP发送单个语句。这比一次使用一个IP快得多。

答案 2 :(得分:1)

如果您可以使用perl编码,则可以使用Memoization http://perldoc.perl.org/Memoize.html 以便在数据库中查找具有相同IP的后续呼叫 NOT

进一步的优化是使用IP的CLass C组件进行查询,以查找是否愿意失去一些准确性。

对from_ip和to_ip以及复合索引进行索引也会有所帮助。

答案 3 :(得分:0)

我发现最简单的方法是按照ips的排序顺序查找 当我查找IP时,我也选择了最后一个IP

喜欢这个

从ip2location选择城市,ToIP,其中FromIP&lt; = $ ipAsInt AND ToIP =&gt; $ ipAsInt

现在,当我必须查找下一个地址时,如果下一个ip已经小于最后一个$ ToIP,那么我不会查询该表

对于每1000个查询,我在这里只查询大约80次。

答案 4 :(得分:0)

事实证明,你可以做得比LIMIT 1好多了!

ip2location website here上显示了如何使用子查询数量级更快

SELECT * FROM ( SELECT * FROM ip2location_db3 WHERE ip_to >= INET_ATON('8.8.8.8') LIMIT 1 ) AS tmp WHERE ip_from <= INET_ATON('8.8.8.8')

在我的MacBook测试中,不同的IP地址花费了不同的时间。性能最差的IP地址具有以下性能:

  • 14s使用BETWEEN而不是LIMIT 1
  • 使用BETWEENLIMIT 1
  • 的300毫秒
  • 2ms使用上面的子选择

快7000倍!