我在 MySQL 中有一个这样的表:
startIp | endIp | 城市 | 国家代码 | 纬度 | 经度 |
---|---|---|---|---|---|
16777216 | 16777471 | 洛杉矶 | 美国 | 34.0522 | -118.244 |
16777472 | 16778239 | 福州 | 中国 | 26.0614 | 119.306 |
16778240 | 16779263 | 墨尔本 | AU | -37.814 | 144.963 |
还有 270 万个条目。
现在我有一个转换后的 IP 地址,如 16777566。
这应该返回“Fzhou, CN, 26.0614, 119.306”
现在我使用这个查询:
SELECT * FROM
kombiniert
WHERE startIp < 16777566 AND endIp > 16777566
它工作得很好,但速度很慢。
性能:
无限制:kombiniert
平均(2300 毫秒)
有限制:SELECT * FROM
平均(1500 毫秒)
kombiniert
WHERE startIp < 2264918979 AND endIp > 2264918979;
无限制地编入索引:kombiniert
平均(5300 毫秒)
索引限制:SELECT * FROM
平均(5500 毫秒)kombiniert
WHERE startIp < 2264918979 AND endIp > 2264918979 LIMIT 1;
编辑:我忘了提及:字段 startIp、endIp 是 bigint!
EDIT2:表创建sql:
kombiniert
答案 0 :(得分:1)
搜索 IP 地址(或任何其他拆分为存储桶的指标)效率不高。或者至少对于明显的代码效率不高。您可以获得的最佳平均性能是扫描表的四分之一以查找您要查找的内容。那就是“订单(N)”。
对于大多数操作,您可以获得“Order(1)”性能,但需要重构表和查询。见http://mysql.rjweb.org/doc.php/ipranges