我订阅了ip2location服务,它以这种格式提供了一个SQL表
FromIP (int), ToIP(int), lat, long, city etc etc
我想解析访问日志并对所有用户进行分类 访问日志具有IP地址和用户ID(比如说)
所以我运行像
这样的查询select city from ip2location where FromIP <= $ipAsInt AND ToIP => $ipAsInt
但这需要花费很长时间才能完成我需要解析的百万条记录。我想这必须是ip2location的一个非常常见的用法。是否可以优化结构?
答案 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)
确保您的表格已在FromIP
和ToIP
上编入索引。
检查数据库,是否具有完整的内存表中的查找功能。
您可能希望将所有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地址具有以下性能:
BETWEEN
而不是LIMIT 1
BETWEEN
与LIMIT 1
快7000倍!