2011-09-26 37 views
1
UPDATE tracker SET t_loc_id=(SELECT cb_loc_id FROM city_blocks WHERE INET_ATON(t_ip) BETWEEN cb_start_ip_num AND cb_end_ip_num LIMIT 1); 

tracker約有300K條記錄,city_blocks約有360萬條記錄。現在已經跑了30分鐘了。如何優化此IP到位置查找查詢?

我已經得到了cb_start_ip_numcb_end_ip_num的唯一索引。

任何方式,我可以加快它?


好吧,我讓它運行了大約2個小時,它只做了大約9K條記錄。

+0

對於開始:取出選擇部分,並執行'desc'以查明其是否正確索引。 – ethrbunny

+0

@ethrbunny:'desc'上的是什麼?確定是否索引了哪個表?跟蹤器表? – mpen

回答

1

http://jcole.us/blog/archives/2007/11/24/on-efficiently-geo-referencing-ips-with-maxmind-geoip-and-mysql-gis/

我轉換我的IP範圍爲多邊形,並添加空間索引,按照所述製品的上方,然後跑我更新查詢:

UPDATE tracker JOIN city_blocks ON mbrcontains(cb_ip_poly, pointfromwkb(point(inet_aton(track_ip),0))) SET t_loc_id=cb_loc_id 

其中在第一時間45秒跑, 8秒,而另一個查詢可能需要10小時到4天。

該文章還提到了傻瓜的解決方案,但它仍然運行速度非常慢。不知道爲什麼...我不知道我的索引是否被破壞(我試圖重建它們),或者它不喜歡在子查詢或其他東西?

說到子查詢......這個解決方案根本不適用於子查詢。我認爲子查詢會更快,因爲我可以添加限制1,它不必將所有內容都加入到所有內容中,但似乎並非如此。在技​​術上沒有限制,它將不得不繼續搜索以查看IP是否屬於其他潛在的匹配/範圍,但我想這在這種情況下並不重要,因爲一切正確索引,並且只有1個桶可以落入至。

+0

感謝您的文章,我會試一試。它可能是我的救助者! – Colandus

2

在上限列(cb_end_ip_num)上創建索引並查找該值大於或等於給定值的第一行。

SELECT * FROM city_blocks WHERE cb_end_ip_num >= 123456789 LIMIT 1

我用這個了的MaxMind,以及它工作得很好。

+0

我想你需要一個'ORDER BY',不是嗎?這假定IP範圍沒有差距。我也在使用maxmind數據庫。 – mpen

+0

這是真的......這假設沒有差距。 – blockhead

+0

這似乎運行同樣緩慢:\ – mpen