所以基本上我有三个表:
CREATE TABLE `cdIPAddressToLocation` (
`IPADDR_FROM` int(10) unsigned NOT NULL COMMENT 'Low end of the IP Address block',
`IPADDR_TO` int(10) unsigned NOT NULL COMMENT 'High end of the IP Address block',
`IPLOCID` int(10) unsigned NOT NULL COMMENT 'The Location ID for the IP Address range',
PRIMARY KEY (`IPADDR_TO`),
KEY `Index_2` USING BTREE (`IPLOCID`),
KEY `Index_3` USING BTREE (`IPADDR_FROM`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE `cdIPLocation` (
`IPLOCID` int(10) unsigned NOT NULL default '0',
`Country` varchar(4) default NULL,
`Region` int(10) unsigned default NULL,
`City` varchar(90) default NULL,
`PostalCode` varchar(10) default NULL,
`Latitude` float NOT NULL,
`Longitude` float NOT NULL,
`MetroCode` varchar(4) default NULL,
`AreaCode` varchar(4) default NULL,
`State` varchar(45) default NULL,
`Continent` varchar(10) default NULL,
PRIMARY KEY (`IPLOCID`)
) ENGINE=MyISAM AUTO_INCREMENT=218611 DEFAULT CHARSET=latin1;
和
CREATE TABLE 'data'{
'IP' varchar(50)
'SCORE' int
}
我的任务是连接这三个表并找到给定 IP 地址的位置数据。我的查询如下:
select
t.ip,
l.Country,
l.State,
l.City,
l.PostalCode,
l.Latitude,
l.Longitude,
t.score
from
(select
ip, inet_aton(ip) ipv, score
from
data
order by score desc
limit 5) t
join
cdIPAddressToLocation a ON t.ipv between a.IPADDR_FROM and a.IPADDR_TO
join
cdIPLocation l ON l.IPLOCID = a.IPLOCID
虽然此查询有效,但速度非常慢,在我的开发盒上返回结果大约需要 100 秒。
我使用的是 mysql 5.1,cdIPAddressToLocation 有 590 万行,cdIPLocation 表有大约 30 万行。
当我检查执行计划时,我发现它没有使用表“cdIPAddressToLocation”中的任何索引,因此对于“数据”表中的每一行,它都会对表“cdIPAddressToLocation”进行全表扫描。这对我来说很奇怪。我的意思是,由于表“cdIPAddressToLocation”中的“IPADDR_FROM”和“IPADDR_TO”列上已经有两个索引,因此执行计划应该利用索引来提高性能,但为什么不使用它们。
还是我的查询有问题?
请帮忙,非常感谢。