Вот запрос:Как я могу улучшить скорость этого запроса MySQL?
SELECT
u.uid as UID,
fuo.uid as FUO_UID,
fo.prid as FO_NAME
FROM
users u
LEFT OUTER JOIN firstpoint_users_organisations fuo ON (u.uid=fuo.uid)
LEFT OUTER JOIN firstpoint_organisations fo ON (fo.nid=fuo.nid)
WHERE
u.status=1 AND u.uid>1
ORDER BY u.uid
LIMIT 3;
скрижали:
users
+------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+------------------+------+-----+---------+----------------+
| uid | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(60) | NO | UNI | | |
| status | tinyint(4) | NO | | 0 | |
+-----------------------------------------------------------------------------+
firstpoint_users_organisations
+-------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| nid | int(10) unsigned | NO | PRI | 0 | |
| uid | int(10) unsigned | NO | PRI | 0 | |
+-------+------------------+------+-----+---------+-------+
firstpoint_organisations
+----------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+------------------+------+-----+---------+-------+
| nid | int(10) unsigned | NO | PRI | 0 | |
| prid | varchar(32) | NO | | | |
+------------------------------------------------------------+
Я хочу показать users.uid
и firstpoint_organisations.prid
для каждой строки в users
, даже если некоторые пользователи не будут иметь prid
, в котором Я показываю NULL (следовательно, левые внешние соединения). Соединение должно быть следующим:
users
uid - firstpoint_users_organisations
\---->uid
nid - firstpoint_organisations
\-------->nid
prid
Таким образом, каждый пользователь (пользователи) имеет идентификатор пользователя (UID), и организации, они связаны с (firstpoint_users_organisation) имеет идентификатор узла (НДИ) и сохраняет эту ассоциацию , Детали организации затем сохраняются в firstpoint_organization.
Таким образом, у каждого пользователя будет prid
, но если они этого не сделают, покажите NULL.
Теперь, если я делаю INNER JOIN на firstpoint_users_organisations
, а затем на firstpoint_organisations
, я получаю хорошую скорость запроса (указанный запрос выполняется за 0,02 секунды). Но когда я переключаю оба на LEFT OUTER JOIN, поэтому я могу получить всех пользователей, prid
или нет prid
, для выполнения вышеуказанного запроса требуется ~ 90 секунд.
Есть ли что-нибудь, что я могу сделать, чтобы ускорить этот запрос? Есть ок. 70 000 строк в таблице users
, но даже с LIMIT 3, делая INNER JOIN LEFT OUTER JOIN занимает ужасное время. Интересно, что запрос занимает столько же времени, что и LIMIT 30, поэтому я думаю, что в моем запросе есть что-то принципиально неправильное.
EXPLAIN по запросу:
+----+-------------+-------+--------+---------------+---------+---------+-----------------------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+-----------------------+-------+----------------------------------------------+
| 1 | SIMPLE | u | range | PRIMARY | PRIMARY | 4 | NULL | 13152 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | fuo | index | NULL | PRIMARY | 8 | NULL | 3745 | Using index |
| 1 | SIMPLE | fo | eq_ref | PRIMARY | PRIMARY | 4 | dbdb-dbdb_uat.fuo.nid | 1 | |
+----+-------------+-------+--------+---------------+---------+---------+-----------------------+-------+----------------------------------------------+
3 rows in set (0.00 sec)
Пожалуйста, пост' EXPLAIN' этого заявления. – Kermit
Один вопрос к вашей таблице firstpoint_users_organisations - возможно ли иметь 2 ПЕРВЫХ ключа? Мне кажется, это немного странно. – Wikunia
Я добавил EXPLAIN, спасибо. 2 первичных ключа в таблице FUO выглядят странно, спасибо за то, что вы заметили. – njp