所以基本上我有三個表:MySQL的聯接不使用索引「之間」運營商
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秒,返回我的dev的框的結果。
我使用mysql 5.1,cdIPAddressToLocation有590萬行,而cdIPLocation表有大約30萬行。
當我檢查執行計劃時,發現它沒有使用表'cdIPAddressToLocation'中的任何索引,因此對於'data'表中的每一行,它都會對錶'cdIPAddressToLocation'執行全表掃描。 這對我來說很奇怪。我的意思是,由於在'IPADDR_FROM'和'IPADDR_TO'列的'cdIPAddressToLocation'表中已經有兩個索引,所以執行計劃應該利用索引來提高性能,但爲什麼它沒有使用它們。
或者我的查詢出現了問題嗎?
請大家幫忙,多謝。
你會發現,如果你切換到使用't.ipv> = a.IPADDR_FROM AND t.ipv <= a.IPADDR_TO'它不會使用索引。我自己也一樣,無法弄清楚。最終將ip表分成多個單獨的表並將查詢發送到基於掩碼的適當範圍,因爲它只是一次性運行。 –