2012-05-25 33 views
0

所以基本上我有三個表: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'表中已經有兩個索引,所以執行計劃應該利用索引來提高性能,但爲什麼它沒有使用它們。

或者我的查詢出現了問題嗎?

請大家幫忙,多謝。

+0

你會發現,如果你切換到使用't.ipv> = a.IPADDR_FROM AND t.ipv <= a.IPADDR_TO'它不會使用索引。我自己也一樣,無法弄清楚。最終將ip表分成多個單獨的表並將查詢發送到基於掩碼的適當範圍,因爲它只是一次性運行。 –

回答