Ik heb een probleem dat MySQL de index niet goed gebruikt.
Ik heb een tabel 'geoname' met ongemeer 7 miljoen records, en wil zoeken op het dichtsbijzijnde record.
Daartoe heb ik onder andere de indexen 'latitude' en 'longitude' gemaakt.
Deze wordt ook gebruikt als ik normaal zoek dmv. 'between a and b' (en is dan ook snel), maar niet als ik er een order by achter zet. Het zoeken duurt dan veel langer. Dit komt m.i. door de filesort.
Even de tabel:
Als ik de volgende query draai:
De explain hiervan is:
Echter, deze query geeft :
De explain hiervan is:
Je ziet dus dat bij de tweede query er een filesort zit. Hierdoor duurt de query erg lang.
Hoe kan ik dit verbeteren?
Ik heb een tabel 'geoname' met ongemeer 7 miljoen records, en wil zoeken op het dichtsbijzijnde record.
Daartoe heb ik onder andere de indexen 'latitude' en 'longitude' gemaakt.
Deze wordt ook gebruikt als ik normaal zoek dmv. 'between a and b' (en is dan ook snel), maar niet als ik er een order by achter zet. Het zoeken duurt dan veel langer. Dit komt m.i. door de filesort.
Even de tabel:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| CREATE TABLE geoname ( geonameid int, name varchar(200), latitude decimal(10,7), longitude decimal(10,7), fclass char(1), fcode varchar(10), country varchar(2), population int, elevation int, moddate date, PRIMARY KEY (`geonameid`), KEY `name` (`name`(10)), KEY `country` (`country`,`admin1`(4),`admin2`(4)), KEY `fclass` (`fclass`,`fcode`(4),`country`), KEY `fcode` (`fcode`(4),`country`), KEY `latitude` (`latitude`), KEY `longitude` (`longitude`), KEY `moddate` (`moddate`) ) ENGINE=MyISAM CHARACTER SET utf8; |
Als ik de volgende query draai:
SQL:
1
2
| select * from geoname where latitude between 52 and 52.2 and longitude between 5.9 and 6.1 |
De explain hiervan is:
code:
1
2
| Id Select_type Table Type Possible_keys Key Key_len Ref Rows Extra 1 SIMPLE geoname range latitude,longitude longitude 7 10081 Using where |
Echter, deze query geeft :
SQL:
1
2
3
4
| select * from geoname where latitude between 52 and 52.2 and longitude between 5.9 and 6.1 order by abs(latitude-52)+abs(longitude-6.0) limit 1 |
De explain hiervan is:
code:
1
2
| Id Select_type Table Type Possible_keys Key Key_len Ref Rows Extra 1 SIMPLE geoname range latitude,longitude longitude 7 10081 Using where; Using filesort |
Je ziet dus dat bij de tweede query er een filesort zit. Hierdoor duurt de query erg lang.
Hoe kan ik dit verbeteren?