2013-11-16 2 views
0

Я следующий запрос:Медленный запрос, что не так?

explain select full_name country_name, cc.country_code_id country_id, 
r.name region_name, r.region_id, wc.accentcity city_name, wc.city_id, 
lower(concat_ws(' ', wc.city, r.name, cc.full_name)) as search1, 
lower(concat_ws(' ', wc.city, cc.full_name)) as search2 
from worldcities wc 
inner join regions r on wc.region = r.region_id 
inner join country_codes cc on wc.country = cc.country_code_id 
-- where city like 'paris%' and full_name like 'fr%' 
having 
search1 like 'paris f%' or 
search2 like 'paris f%'; 

, который выводит это:

+----+-------------+-------+--------+----------------+----------------+---------+-----------------------------+------+-------------+ 
| id | select_type | table | type | possible_keys | key   | key_len | ref       | rows | Extra  | 
+----+-------------+-------+--------+----------------+----------------+---------+-----------------------------+------+-------------+ 
| 1 | SIMPLE  | cc | index | PRIMARY  | full_name  | 144  | NULL      | 315 | Using index | 
| 1 | SIMPLE  | wc | ref | country_region | country_region | 4  | vpromote.cc.country_code_id | 2544 |    | 
| 1 | SIMPLE  | r  | eq_ref | PRIMARY  | PRIMARY  | 4  | vpromote.wc.region   | 1 |    | 
+----+-------------+-------+--------+----------------+----------------+---------+-----------------------------+------+-------------+ 

Вот индексы на worldcities

+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
| Table  | Non_unique | Key_name  | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | 
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
| worldcities |   0 | PRIMARY  |   1 | city_id  | A   |  3170651 |  NULL | NULL |  | BTREE  |   |    | 
| worldcities |   1 | city   |   1 | city  | A   |  3170651 |  NULL | NULL |  | BTREE  |   |    | 
| worldcities |   1 | country_region |   1 | country  | A   |   18 |  NULL | NULL |  | BTREE  |   |    | 
| worldcities |   1 | country_region |   2 | region  | A   |  1254 |  NULL | NULL |  | BTREE  |   |    | 
+-------------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 

здесь таблицы:

mysql> explain worldcities; 
+------------+------------------+------+-----+---------+----------------+ 
| Field  | Type    | Null | Key | Default | Extra   | 
+------------+------------------+------+-----+---------+----------------+ 
| city_id | int(10) unsigned | NO | PRI | NULL | auto_increment | 
| country | int(10) unsigned | NO | MUL | NULL |    | 
| region  | int(10) unsigned | NO |  | NULL |    | 
| city  | varchar(65)  | NO | MUL | NULL |    | 
| accentcity | varchar(65)  | NO |  | NULL |    | 
+------------+------------------+------+-----+---------+----------------+ 

mysql> explain regions; 
+-----------+------------------+------+-----+---------+----------------+ 
| Field  | Type    | Null | Key | Default | Extra   | 
+-----------+------------------+------+-----+---------+----------------+ 
| region_id | int(10) unsigned | NO | PRI | NULL | auto_increment | 
| country | int(10) unsigned | YES |  | NULL |    | 
| region | char(2)   | NO | MUL | NULL |    | 
| name  | varchar(115)  | NO | MUL | NULL |    | 
+-----------+------------------+------+-----+---------+----------------+ 

mysql> explain country_codes; 
+-----------------+------------------+------+-----+---------+----------------+ 
| Field   | Type    | Null | Key | Default | Extra   | 
+-----------------+------------------+------+-----+---------+----------------+ 
| country_code_id | int(10) unsigned | NO | PRI | NULL | auto_increment | 
| full_name  | char(48)   | NO | MUL | NULL |    | 
| short_code  | char(3)   | NO | MUL | NULL |    | 
| listing_order | int(11)   | NO |  | 0  |    | 
+-----------------+------------------+------+-----+---------+----------------+ 

Я не могу понять, что делать, чтобы ускорить это, этот запрос занимает около 9 секунд.
У меня есть еще один запрос, который занимает менее 1 секунды, но она не возвращает результатов и выглядит следующим образом:

select full_name country_name, cc.country_code_id country_id, 
r.name region_name, r.region_id, wc.accentcity city_name, wc.city_id 
from worldcities wc 
inner join regions r on wc.region = r.region_id 
inner join country_codes cc on wc.country = cc.country_code_id and r.country = cc.country_code_id 
where full_name like 'fr%' 

Итак, что я могу сделать, чтобы ускорить первый один вверх?

+0

Диском выберите в вид, так что '' search1'' и '' search2'' являются просмотреть столбцы, а затем добавить индекс для каждого из них. – acfrancis

+1

В MySQL нет понятия добавления индекса в представление. –

+0

все ваши индексирование и оптимизация не будут иметь особого различия с поиском подстановочных знаков .... вам нужно сканировать всю таблицу, когда вы говорите такие вещи, как 'search1 like 'paris f%' Я предлагаю вам перепроектировать вашу схему так что 1) вы избегаете подстановочных знаков 2), если вы должны выполнять поиск по шаблону, вы сканируете наименьший объем данных с минимальным количеством подключений. – mrkb80

ответ

0

Почему бы не сделать:

select full_name country_name, cc.country_code_id country_id, 
r.name region_name, r.region_id, wc.accentcity city_name, wc.city_id, 
lower(concat_ws(' ', wc.city, r.name, cc.full_name)) as search1, 
lower(concat_ws(' ', wc.city, cc.full_name)) as search2 
from (select accentcity city_name, city_id, city from worldcities where city='paris') as wc 
inner join regions r on wc.region = r.region_id 
inner join country_codes cc on wc.country = cc.country_code_id 
-- where city like 'paris%' and full_name like 'fr%' 
; 

(или where city like 'paris%' в зависимости от того, что название города может быть)

Смежные вопросы