индексы и ускорение «производных» запросов

Недавно я заметил, что мой запрос выполняется довольно медленно, почти 1 секунду на запрос.

Запрос выглядит так

SELECT eventdate.id, 
        eventdate.eid, 
        eventdate.date, 
        eventdate.time, 
        eventdate.title, 
        eventdate.address, 
        eventdate.rank, 
        eventdate.city, 
        eventdate.state, 
        eventdate.name, 
        source.link, 
        type, 
        eventdate.img 
FROM source 
RIGHT OUTER JOIN 
(
    SELECT event.id, 
            event.date, 
            users.name,  
            users.rank, 
            users.eid, 
            event.address, 
            event.city, 
            event.state, 
            event.lat, 
            event.`long`, 
            GROUP_CONCAT(types.type SEPARATOR ' | ') AS type 
    FROM event FORCE INDEX (latlong_idx) 
    JOIN users ON event.uid = users.id 
    JOIN types ON users.tid=types.id 
    WHERE `long` BETWEEN -74.36829174058 AND -73.64365405942 
    AND lat BETWEEN 40.35195025942 AND 41.07658794058 
    AND event.date >= '2009-10-15' 
    GROUP BY event.id, event.date
    ORDER BY event.date, users.rank DESC 
    LIMIT 0, 20 
)eventdate 
ON eventdate.uid = source.uid 
AND eventdate.date = source.date;

и объяснение

+----+-------------+------------+--------+---------------+-------------+---------+------------------------------+-------+---------------------------------+
| id | select_type | table      | type   | possible_keys | key         | key_len | ref                          | rows  | Extra                           |
+----+-------------+------------+--------+---------------+-------------+---------+------------------------------+-------+---------------------------------+
|  1 | PRIMARY     |            | ALL    | NULL          | NULL        | NULL    | NULL                         |    20 |                                 |
|  1 | PRIMARY     | source     | ref    | iddate_idx    | iddate_idx  | 7       | eventdate.id,eventdate.date  |   156 |                                 |
|  2 | DERIVED     | event      | ALL    | latlong_idx   | NULL        | NULL    | NULL                         | 19500 | Using temporary; Using filesort |
|  2 | DERIVED     | types      | ref    | eid_idx       | eid_idx     | 4       | active.event.id              | 10674 | Using index                     |
|  2 | DERIVED     | users      | eq_ref | id_idx        | id_idx      | 4       | active.types.id              |     1 | Using where                     |
+----+-------------+------------+--------+---------------+-------------+---------+------------------------------+-------+---------------------------------+

Я пытался использовать «индекс силы» для latlong, но, похоже, это совсем не ускоряет работу.

Является ли производная таблица причиной медленных ответов? Если да, то есть ли способ улучшить производительность этого?

-------- РЕДАКТИРОВАТЬ ------------- Я попытался улучшить форматирование, чтобы сделать его более читабельным

Я запускаю тот же запрос, изменяя только оператор WHERE как

WHERE users.id = (
SELECT users.id
FROM users
WHERE uidname = 'frankt1'
ORDER BY users.approved DESC , users.rank DESC
LIMIT 1 )
AND date & gt ; = '2009-10-15'
GROUP BY date
ORDER BY date)

Этот запрос выполняется за 0,006 секунды.

объяснение выглядит так

+----+-------------+------------+-------+---------------+---------------+---------+------------------------------+------+----------------+
| id | select_type | table      | type  | possible_keys | key           | key_len | ref                          | rows | Extra          |
+----+-------------+------------+-------+---------------+---------------+---------+------------------------------+------+----------------+
|  1 | PRIMARY     |            | ALL   | NULL          | NULL          | NULL    | NULL                         |   42 |                |
|  1 | PRIMARY     | source     | ref   | iddate_idx    |  iddate_idx   | 7       | eventdate.id,eventdate.date  |  156 |                |
|  2 | DERIVED     | users      | const | id_idx        |  id_idx       | 4       |                              |    1 |                |
|  2 | DERIVED     | event      | range | eiddate_idx   | eiddate_idx   | 7       | NULL                         |   24 | Using where    |
|  2 | DERIVED     | types      | ref   | eid_idx       | eid_idx       | 4       | active.event.bid             |    3 | Using index    |
|  3 | SUBQUERY    | users      | ALL   | idname_idx    | idname_idx    | 767     |                              |    5 | Using filesort |
+----+-------------+------------+-------+---------------+---------------+---------+------------------------------+------+----------------+

person pedalpete    schedule 15.10.2009    source источник
comment
Улучшить форматирование кода. Добавьте отступы, уберите ненужные поля из SELECT.   -  person Lukasz Lysik    schedule 16.10.2009


Ответы (1)


Единственный способ очистить этот гигантский оператор SQL — вернуться к чертежной доске и тщательно проработать структуру и требования вашей базы данных. Как только вы начнете присоединяться к 6 таблицам и использовать внутренний выбор, вы должны ожидать невероятного времени выполнения.

Для начала убедитесь, что все поля вашего идентификатора проиндексированы, но лучше убедитесь, что ваш дизайн действителен. Я не знаю, с чего НАЧАТЬ смотреть на ваш SQL - даже после того, как я переформатировал его для вас.

Обратите внимание, что «использование индексов» означает, что вам нужно выдавать правильные инструкции при СОЗДАНИИ или ИЗМЕНЕНИИ таблиц, которые вы используете. См., например, создание индексов MySql 5.0

person Tom Leys    schedule 15.10.2009
comment
объединение 6 способностей НЕ является большим объединением. Объединение 6 таблиц с правильными индексами не должно быть проблемой... - person Mitch Wheat; 16.10.2009
comment
спасибо, Митч, я не думал, что о соединении с 6 таблицами не может быть и речи, так как я получаю тот же запрос с другим оператором WHERE и получаю время отклика 0,006 секунды. - person pedalpete; 16.10.2009