我有一個InnoDB MySql地理標識表,有大約100萬行。該表的結構是這樣的:如何進一步優化這個MySQL表的單個查詢
CREATE TABLE `geoid` (
`start_ip` int(11) NOT NULL,
`end_ip` int(11) NOT NULL,
`city` varchar(64) NOT NULL,
`region` char(2) NOT NULL,
PRIMARY KEY (`start_ip`,`end_ip`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
只會有一種類型的查詢運行對這個表:
SELECT city, region FROM geoid WHERE 1259650516 BETWEEN start_ip AND end_ip
這個查詢約需〜0.4228秒,這是不超慢,但不是快得令人難以置信醚。
我的問題是:如何進一步優化我的表,這個單一的查詢?
我曾嘗試以下的事情:
- 改變存儲引擎MyISAM數據,本作的查詢需要大約1.9秒。
- 使用WHERE語句'WHERE geoid.start_ip < = 1259650516 AND 1259650516 < = geoid.end_ip'。但這需要約0.5秒來執行,而不是.4 ish。
我已經從表中刪除了所有無用的行,使它變小。我需要所有100萬行。
UPDATE /解決方案
由於下面的文章,這裏是我做過什麼來解決這個問題。 (只是爲了完成這個答案對於任何人感興趣)
我添加了一個新的列上表:
ALTER TABLE `geoid` ADD `geoip` LINESTRING NOT NULL
然後,我從start_ip地理數據填充新列和起點ip-終點
GeomFromText(CONCAT('LINESTRING(', start_ip, ' -1, ', end_ip, ' 1)'))
我然後創建空間索引對新列
CREATE SPATIAL INDEX geoip_index ON geoid(geoip);
從那裏,所有的你必須做的是改變你的查詢爲:
SELECT city, region FROM geoid WHERE MBRContains(geoip, GeomFromText(CONCAT('POINT(', 1259650516, ' 0)')));
和你的完成。這將查詢從.42秒降至.0003秒!!!!!!!
我喜歡這個INDEX。謝謝。希望能幫助到你。
您在'InnoDB'表上創建了一個'SPATIAL'索引? – Quassnoi
我先將它轉換爲MyISAM。 – RonSper