我有一个InnoDB MySql Geo ID表,有大约100万行。表结构如下:
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
这个查询需要大约〜.4228秒,这不是超级慢但不是非常快的以太。
我的问题是:如何针对此单个查询进一步优化我的表格?
我尝试了以下事项:
我已从表中删除所有无用的行以使其变小。我需要所有100万行。
更新/解决方案
感谢下面的文章,这是我为解决这个问题所做的工作。 (只是为其他感兴趣的人完成这个答案)
我在上表中添加了一个新列:
ALTER TABLE `geoid` ADD `geoip` LINESTRING NOT NULL
然后我用start_ip和end_ip
中的地理数据填充了新列GeomFromText(CONCAT('LINESTRING(', start_ip, ' -1, ', end_ip, ' 1)'))
然后我在新列上创建了SPATIAL INDEX
CREATE SPATIAL INDEX geoip_index ON geoid(geoip);
从那里,您所要做的就是将查询更改为:
SELECT city, region FROM geoid WHERE MBRContains(geoip, GeomFromText(CONCAT('POINT(', 1259650516, ' 0)')));
和你完成。这使得查询从.42秒降低到.0003秒!!!!!!!
我喜欢这个INDEX。谢谢。希望它有所帮助。
答案 0 :(得分:3)
尝试在end_ip
上添加索引。在某些情况下,这应该使查询的速度提高一倍。
要获得更好的性能,您需要使用SPATIAL索引,如this article中所述。
答案 1 :(得分:0)
尝试在查询中包含的所有字段上创建索引。在这个特殊情况下,在两个字段(start_ip和end_ip)上创建一个索引