索引和加速'派生'查询

时间:2009-10-15 23:19:43

标签: mysql derived-table

我最近注意到我的查询运行速度很慢,每次查询差不多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上使用'force index',但这似乎并没有加快速度。

派生表导致响应缓慢吗?如果是这样,有没有办法提高性能呢?

-------- ------------- EDIT 我试图改进格式以使其更具可读性

我运行相同的查询,仅将'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 |
+----+-------------+------------+-------+---------------+---------------+---------+------------------------------+------+----------------+

1 个答案:

答案 0 :(得分:1)

清理庞大的SQL语句的唯一方法是回到绘图板并仔细地处理您的数据库设计和要求。一旦你开始加入6个表并使用内部选择,你应该期望不可思议的执行时间。

首先,请确保为您的所有ID字段编制索引,但最好确保您的设计有效。我不知道在哪里开始查看你的SQL - 即使我为你重新格式化它。

请注意,“使用索引”表示在创建或更改正在使用的表时需要发出正确的说明。例如,请参阅MySql 5.0 create indexes