Я думаю, вы должны сначала изменить свой стол.
Сортировка столбцов asciiname
, feature_class
, feature_code
, country_code
, cc2
, adminN
, timezone
следует изменить на latin1_general_ci
.Это снизит требования к хранилищу данных как для данных, так и для индексов и позволит серверу разместить больше данных в буферах при выполнении запросов.
Вы должны изменить тип данных population
на INTEGER UNSIGNED , как в данный момент вашданные, вероятно, усечены для некоторых записей (проверьте значение для «Содружества наций»).Вы также можете рассмотреть возможность изменения moddate
на DATE, elevation
и gtopo30
на SMALLINT для дальнейшего снижения требований к хранилищу.
Затем вам нужно изменить индекс geoname_admin1_idx с:
INDEX `geoname_admin1_idx` (`admin1`)
to:
INDEX `geoname_admin1_idx` (`feature_code`, `admin1`)
Сделайте то же самое для других индексов geoname_adminN_idx.Это позволит серверу выполнять соединения в запросе намного быстрее.
Эти изменения имеют огромное значение и уменьшают время выполнения запроса в моей системе с 8 до почти нуля (0,1 с) без изменения запроса.
Объясните результаты после этих изменений:
mysql> explain
-> SELECT t0.preferredname,
-> t4.preferredname AS town,
-> t3.preferredname AS county,
-> t2.preferredname AS district,
-> t1.preferredname AS admin1
-> , MIN(t0.geonameid)
-> FROM geoname t0
-> LEFT JOIN geoname t1 ON t1.admin1 = t0.admin1 AND t1.feature_code = 'ADM1'
-> LEFT JOIN geoname t2 ON t2.admin2 = t0.admin2 AND t2.feature_code = 'ADM2'
-> LEFT JOIN geoname t3 ON t3.admin3 = t0.admin3 AND t3.feature_code = 'ADM3'
-> LEFT JOIN geoname t4 ON t4.admin4 = t0.admin4 AND t4.feature_code = 'ADM4'
-> WHERE t0.feature_class IN ('P', 'A')
-> AND t0.preferredname LIKE 'preston%'
-> GROUP BY t0.preferredname,
-> t4.preferredname,
-> t3.preferredname,
-> t2.preferredname,
-> t1.preferredname;
+----+-------------+-------+------------+-------+-----------------------------------------------------------------------------+---------------------------+---------+----------------------+------+----------+---------------------------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+-----------------------------------------------------------------------------+---------------------------+---------+----------------------+------+----------+---------------------------------------------------------------------+
| 1 | SIMPLE | t0 | NULL | range | geoname_preferredname_idx,geoname_feature_class_idx | geoname_preferredname_idx | 803 | NULL | 55 | 68.74 | Using index condition; Using where; Using temporary; Using filesort |
| 1 | SIMPLE | t1 | NULL | ref | geoname_admin1_idx,geoname_admin2_idx,geoname_admin3_idx,geoname_admin4_idx | geoname_admin2_idx | 13 | const | 4 | 100.00 | Using where |
| 1 | SIMPLE | t2 | NULL | ref | geoname_admin1_idx,geoname_admin2_idx,geoname_admin3_idx,geoname_admin4_idx | geoname_admin2_idx | 96 | const,test.t0.admin2 | 10 | 100.00 | NULL |
| 1 | SIMPLE | t3 | NULL | ref | geoname_admin1_idx,geoname_admin2_idx,geoname_admin3_idx,geoname_admin4_idx | geoname_admin3_idx | 36 | const,test.t0.admin3 | 4 | 100.00 | NULL |
| 1 | SIMPLE | t4 | NULL | ref | geoname_admin1_idx,geoname_admin2_idx,geoname_admin3_idx,geoname_admin4_idx | geoname_admin4_idx | 36 | const,test.t0.admin4 | 3 | 100.00 | NULL |
+----+-------------+-------+------------+-------+-----------------------------------------------------------------------------+---------------------------+---------+----------------------+------+----------+---------------------------------------------------------------------+
Проверьте key_len, ref, строки и дополнительные для присоединения к таблицам.
Используемый вами запрос может также извлечь выгоду из индекса (feature_class, предпочитаемое имя).Вот объяснение с индексом:
+----+-------------+-------+------------+-------+------------------------------------------------------------------------------------------------------+-----------------------------------------+---------+----------------------+------+----------+--------------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+------------------------------------------------------------------------------------------------------+-----------------------------------------+---------+----------------------+------+----------+--------------------------------------------------------+
| 1 | SIMPLE | t0 | NULL | range | geoname_preferredname_idx,geoname_feature_class_idx,geoname_feature_class_preferredname_idx | geoname_feature_class_preferredname_idx | 805 | NULL | 42 | 100.00 | Using index condition; Using temporary; Using filesort |
| 1 | SIMPLE | t1 | NULL | ref | geoname_admin1_idx,geoname_admin2_idx,geoname_admin3_idx,geoname_admin4_idx,geoname_feature_code_idx | geoname_admin2_idx | 13 | const | 4 | 100.00 | Using where |
| 1 | SIMPLE | t2 | NULL | ref | geoname_admin1_idx,geoname_admin2_idx,geoname_admin3_idx,geoname_admin4_idx,geoname_feature_code_idx | geoname_admin2_idx | 96 | const,test.t0.admin2 | 12 | 100.00 | NULL |
| 1 | SIMPLE | t3 | NULL | ref | geoname_admin1_idx,geoname_admin2_idx,geoname_admin3_idx,geoname_admin4_idx,geoname_feature_code_idx | geoname_admin3_idx | 36 | const,test.t0.admin3 | 4 | 100.00 | NULL |
| 1 | SIMPLE | t4 | NULL | ref | geoname_admin1_idx,geoname_admin2_idx,geoname_admin3_idx,geoname_admin4_idx,geoname_feature_code_idx | geoname_admin4_idx | 36 | const,test.t0.admin4 | 3 | 100.00 | NULL |
+----+-------------+-------+------------+-------+------------------------------------------------------------------------------------------------------+-----------------------------------------+---------+----------------------+------+----------+--------------------------------------------------------+