I have a table Postcode which holds all UK postcode (approx 1.8m i think)
CREATE TABLE `Postcode` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Postcode` varchar(8) DEFAULT NULL,
`Postcode_Simple` varchar(8) DEFAULT NULL,
`Positional_Quality_Indicator` int(11) DEFAULT NULL,
`Eastings` int(11) DEFAULT NULL,
`Northings` int(11) DEFAULT NULL,
`Latitude` double DEFAULT NULL,
`Longitude` double DEFAULT NULL,
`LatLong` point DEFAULT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `Postcode` (`Postcode`),
KEY `Postcode_Simple` (`Postcode_Simple`),
KEY `LatLong` (`LatLong`(25))
) ENGINE=InnoDB AUTO_INCREMENT=1755933 DEFAULT CHARSET=latin1;
What I want to achieve is...Given a co-ordinate, locate the postcode nearest to the co-ordinate. Problem is I'm having a bit of an issue with the query (actually in a stored procedure) I've written to do this. The query is:
SELECT
Postcode
FROM
(SELECT
Postcode,
GLENGTH(
LINESTRINGFROMWKB(
LINESTRING(
LatLong,
GEOMFROMTEXT(CONCAT('POINT(', varLatitude, ' ', varLongitude, ')'))
)
)
) AS distance
FROM
Postcode
WHERE
NOT LatLong IS NULL) P
ORDER BY
Distance
LIMIT
1;
The problem I'm having is that the query takes some 12seconds to run and I cannot have it take that long to get a result. Can anyone think of any ways I can reliably speed this query up?
(Here's the explain for the query)
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL (NULL) (NULL) (NULL) (NULL) 1688034 Using filesort
2 DERIVED Postcode ALL LatLong (NULL) (NULL) (NULL) 1717998 Using where
I've been trying to think of a way to narrow down the initial amount of data that I must perform the distance calculation on, but I haven't been able to come up with anything that doesn't restrict to finding postcodes within a given distance.