У меня есть устаревшая таблица innodb Listing, содержащая бизнес с широтой / долготой. Учитывая введенные значения широты / долготы (ниже 51,2167 / 4,41667), запрос должен вернуть первые 30 активных, включенных, не удаленных предприятий в порядке их близости (в километрах). Соединение с таблицей учетных записей выполняется для проверки действительности листинга.
select
listing.*
from
listing listing ,
account account
where
listing.account_id = account.id
and listing.active = 1
and listing.approved = 1
and listing.deleted = 0
and listing.enabled = 1
and account.enabled = 1
and account.activated_by_user = 1
group by
listing.id
having
111.222569*degrees(acos(sin(radians(listing.latitude))*sin(radians( 51.2167)) +cos(radians(listing.latitude))*cos(radians( 51.2167))*cos(radians(listing.longitude - 4.41667)))) < 250
order by
111.222569*degrees(acos(sin(radians(listing.latitude))*sin(radians( 51.2167)) +cos(radians(listing.latitude))*cos(radians( 51.2167))*cos(radians(listing.longitude - 4.41667))))
limit 30;
Каждая таблица Listing и Account содержит более 50 000 строк, но выполнение запроса все равно занимает в среднем 24 секунды. Без порядка по это занимает 17 секунд.
Я уже пробовал установить некоторые индексы на «активный», «утвержденный», «удаленный», «включенный». Могу ли я переписать запрос или добавить определенные индексы для эффективного выполнения этого запроса - без изменения структуры таблицы?
+----+-------------+---------+-------------+-------------------------------------------------------------------------------------------------+-----------------------------------------------------------------+---------+------------------------+------+--------------------------------------------------------------------------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------------+-------------------------------------------------------------------------------------------------+-----------------------------------------------------------------+---------+------------------------+------+--------------------------------------------------------------------------------------------------------------------------------+
| 1 | SIMPLE | listing | index_merge | FKB4DC521D9306A80C,listing_active,listing_approved,listing_enabled,listing_deleted,index_test_1 | listing_active,listing_approved,listing_enabled,listing_deleted | 1,1,1,1 | NULL | 3392 | Using intersect(listing_active,listing_approved,listing_enabled,listing_deleted); Using where; Using temporary; Using filesort |
| 1 | SIMPLE | account | eq_ref | PRIMARY,account_enabled,account_activated_by_user,index_test_2 | PRIMARY | 8 | ctm.listing.account_id | 1 | Using where |
+----+-------------+---------+-------------+-------------------------------------------------------------------------------------------------+-----------------------------------------------------------------+---------+------------------------+------+--------------------------------------------------------------------------------------------------------------------------------+
Любая помощь приветствуется.