Этот запрос выполняется очень медленно. Принимает между 9 и 10 секунд ...Любой способ ускорить этот запрос?
SELECT DISTINCT a.*
FROM addresses a
LEFT JOIN contacts c
ON c.id = a.contact_id
LEFT JOIN organizations o
ON o.id = a.organization_id
ORDER BY c.last_name, c.first_name, o.name
LIMIT 0, 24
Если я закомментируйте пункт ORDER BY
запрос работает гораздо быстрее - около 5 миллисекунд. Но мне нужен ORDER BY
для поддержки поиска поисковых запросов. И пользователям нужны адреса для сортировки по контактам и организации.
Структура таблицы
addresses
---------
id int NOT NULL
contact_id int # could be NULL
organization_id int # could be NULL
contacts
--------
id int NOT NULL
first_name varchar(255)
last_name varchar(255)
organizations
-------------
id int NOT NULL
name varchar(255)
Они все таблицы InnoDB.
У меня есть эти индексы на контакты таблице:
KEY `idx_contacts_first_name` (`first_name`),
KEY `idx_contacts_last_name` (`last_name`),
KEY `idx_contacts_first_name_last_name` (`first_name`,`last_name`)
И на организации таблицы:
KEY `idx_organization_name` (`name`)
Количество данных
Addresses: 22,271
Contacts: 17,906
Organizations: 8,246
ОПИСАТЬ OUTPUT
mysql> DESCRIBE
-> SELECT DISTINCT a.*
-> FROM addresses a
-> LEFT JOIN contacts c
-> ON c.id = a.contact_id
-> LEFT JOIN organizations o
-> ON o.id = a.organization_id
-> ORDER BY c.last_name, c.first_name, o.name
-> LIMIT 0, 24;
+----+-------------+-------+--------+---------------+---------+---------+--------------------------------------------+-------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+--------------------------------------------+-------+---------------------------------+
| 1 | SIMPLE | a | ALL | NULL | NULL | NULL | NULL | 22387 | Using temporary; Using filesort |
| 1 | SIMPLE | c | eq_ref | PRIMARY | PRIMARY | 4 | contactdb_v2_development.a.contact_id | 1 | Distinct |
| 1 | SIMPLE | o | eq_ref | PRIMARY | PRIMARY | 4 | contactdb_v2_development.a.organization_id | 1 | Distinct |
+----+-------------+-------+--------+---------------+---------+---------+--------------------------------------------+-------+---------------------------------+
3 rows in set (0.00 sec)
Что вы подразумеваете под «сделайте свой заказ и подкачку на этом уровне»? Вы предлагаете выполнить сортировку в коде приложения после извлечения данных из БД? – sleske
Да. Для набора данных в 20 000 строк, который, вероятно, не изменится так сильно, было бы целесообразно вытащить данные, отсортировать их и кешировать. –
Да, я думаю, что буду использовать что-то вроде этого. Может показаться странным получить все записи и предложить их для подкачки, но это не приведет к болезненным сложностям интерфейса. – Ethan