我总共有三张桌子,一张有玩家名字和最后一张登录,另一张桌子有玩家名字和他们的IP。这些来自游戏服务器,但它是服务器的两个独立的“插件”,所以我不能将它们合并到一个表中。
我在playername
列上成功加入了这两个:
SELECT
u.`user` as `ign`,
lb.`lastlogin` as `date`,
lb.`ip`
FROM `mcmmo_users` u
LEFT JOIN `lb-players` lb
ON u.`user`=lb.`playername`
这些产生以下数组:Array(ign,date,ip);
但是,我也有一个IP2C(IP-Country)表,我想同时得到这些结果。但是,这个表非常大,如果我做了标准的LEFT JOIN,会大大减慢查询速度。
有更快的方式加入吗?我宁愿不查询数据的每个PHP循环。
我正在使用MySQL和PHP
IP2C数据库的布局如下:
begin_ip | end_ip | begin_ip_num | end_ip_num | country_code | country_name
并且查询如下:
$IPNUM = sprintf("%u",ip2long($ip));
SELECT `country_code`
FROM `cpanel_ip2c`
WHERE `$IPNUM` BETWEEN `begin_ip_num` AND `end_ip_num`
答案 0 :(得分:2)
很难为数据库优化between
条件。相反,请考虑查询大于或等于用户IP的第一个IP块:
select *
from mcmmo_users u
left join
`lb-players` lb
on u.user = lb.playername
left join
cpanel_ip2c ip
on ip.begin_ip_num =
(
select begin_ip_num
from cpanel_ip2c ip
where ip.begin_ip_num <= inet_aton(lb.ip)
order by
ip.begin_ip_num desc
limit 1
)
and inet_aton(lb.ip) <= ip.end_ip_num
使用cpanel_ip2c(begin_ip_num )
上的索引,可以使用索引搜索来解析该国家/地区。
这是一个example on SQL Fiddle,为简单起见省略了mcmmo_users
表。