How to further optimize this MySQL table for a single Query
I have a InnoDB MySql Geo ID table that has ~ 1 million rows. The table structure is this:
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;
There will only be one type query ran against this table:
SELECT city, region FROM geoid WHERE 1259650516 BETWEEN start_ip AND end_ip
This query takes about ~ .4228 sec, which is not super slow but not incredibly fast ether.
My question is: How can I further optimize my table for this single query?
I have tried the following things开发者_Go百科:
- Change the Storage Engine to MyISAM, this made the query take about 1.9 sec.
- Use the WHERE statement 'WHERE geoid.start_ip <= 1259650516 AND 1259650516 <= geoid.end_ip'. But that takes about .5 sec to execute instead of .4 ish.
I have removed all useless rows from the table to make it smaller. I need all 1 million rows.
UPDATE / SOLUTION
Thanks to the article below, here is what I did to fix this problem. (just to complete this answer for anyone else interested)
I added a new column to the above table:
ALTER TABLE `geoid` ADD `geoip` LINESTRING NOT NULL
I then filled the new column with the geo data from start_ip and end_ip
GeomFromText(CONCAT('LINESTRING(', start_ip, ' -1, ', end_ip, ' 1)'))
I then created the SPATIAL INDEX on the new column
CREATE SPATIAL INDEX geoip_index ON geoid(geoip);
From there, all you have to do is change your query to:
SELECT city, region FROM geoid WHERE MBRContains(geoip, GeomFromText(CONCAT('POINT(', 1259650516, ' 0)')));
AND YOUR DONE. This took the query down from .42 sec to .0003 sec!!!!!!!
I love this INDEX. Thank you. Hope it helps.
Try adding an index on end_ip
. This should make the query about twice as fast in some cases.
For much better perfomance you need to use a SPATIAL index, as explained in this article.
Try to create index on all fields included in query. on this particular case create one index on two fields (start_ip and end_ip)
精彩评论