【发布时间】:2017-04-26 01:44:47
【问题描述】:
我有一个 PHP/MySQL geo-ip 脚本,它获取用户的 IP 地址,将其转换为长整数并在 IP 范围表中搜索用户 IP 所在的单个地理位置 ID:
$iplong = ip2long($_SERVER['REMOTE_ADDR']);
SELECT id FROM geoip
WHERE ".$iplong." BETWEEN range_begin AND range_end
ORDER BY range_begin DESC LIMIT 1
“geoip”表包含 250 万行。 “range_begin”和“range_end”列都是唯一索引。 IP范围似乎没有重叠。有时这个查询需要大约 1 秒才能完成,但我希望有办法改进它,因为它是我网站上最慢的查询。
谢谢
编辑:我将查询更改为:
SELECT * FROM geoip
WHERE range_begin <= ".$iplong." AND range_end >= ".$iplong."
ORDER BY range_begin DESC LIMIT 1
我现在有一个唯一的综合指数(range_begin,range_end)。我使用了“EXPLAIN”功能,看起来它仍然搜索了 120 万行:
id: 1
select_type: Simple
table: geoip
type: range
possible_keys: range_begin
key: range_begin
key_len: 8
ref: NULL
rows: 1282026
Extra: Using Index Condition
【问题讨论】:
-
where range_begin<=iplong and range_end>=iplong有什么改善吗?我认为它会是一样的,但我会先尝试这个.. 复合索引 (range_begin, range_end) 也应该有帮助 -
我更改了查询并创建了一个复合索引。它似乎工作得更好,不过我见过的最长查询时间是 0.30 秒。我可以发誓我之前尝试过这个但它没有用(从 0.001 秒到 4 秒的速度不一致),仍然不确定我看到的是实际查询时间还是缓存查询时间 - 我会留意它.谢谢
-
我只看到它运行在0.81秒,查询时间仍然很不一致,变化很大。
-
请注意,我现在拥有的索引是唯一的综合索引(range_begin,range_end)。也许这是最快的速度?
-
@peppy - 0.001s 可能意味着“查询缓存”处于活动状态,并且您刚刚运行了相同的查询。