索引并加速“派生”;查询

发布于 2024-08-08 09:51:14 字数 4424 浏览 5 评论 0原文

我最近注意到我的一个查询运行速度非常慢,每个查询几乎需要 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                     |
+----+-------------+------------+--------+---------------+-------------+---------+------------------------------+-------+---------------------------------+

我尝试在经纬度上使用“强制索引”,但这似乎根本没有加快速度。

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

- - - - 编辑 - - - - - - - 我尝试改进格式以使其更具可读性,并且

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

I've recently noticed that a query I have is running quite slowly, at almost 1 second per query.

The query looks like this

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;

and the explain is

+----+-------------+------------+--------+---------------+-------------+---------+------------------------------+-------+---------------------------------+
| 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                     |
+----+-------------+------------+--------+---------------+-------------+---------+------------------------------+-------+---------------------------------+

I've tried using 'force index' on latlong, but that doesn't seem to speed things up at all.

Is it the derived table that is causing the slow responses? If so, is there a way to improve the performance of this?

--------EDIT-------------
I've attempted to improve the formatting to make it more readable, as well

I run the same query changing only the 'WHERE statement as

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)

That query runs in 0.006 seconds

the explain looks like

+----+-------------+------------+-------+---------------+---------------+---------+------------------------------+------+----------------+
| 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 |
+----+-------------+------------+-------+---------------+---------------+---------+------------------------------+------+----------------+

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情愿 2024-08-15 09:51:14

清理庞大 SQL 语句的唯一方法是回到绘图板并仔细研究数据库设计和需求。一旦您开始连接 6 个表并使用内部选择,您就应该期待令人难以置信的执行时间。

首先,确保所有 id 字段都已建立索引,但最好确保您的设计有效。我不知道从哪里开始查看你的 SQL - 即使我为你重新格式化了它。

请注意,“使用索引”意味着您在创建或更改正在使用的表时需要发出正确的指令。例如,请参见 MySql 5.0 创建索引

The only way to clean up that mammoth SQL statement is to go back to the drawing board and carefully work though your database design and requirements. As soon as you start joining 6 tables and using an inner select you should expect incredible execution times.

As a start, ensure that all your id fields are indexed, but better to ensure that your design is valid. I don't know where to START looking at your SQL - even after I reformatted it for you.

Note that 'using indexes' means you need to issue the correct instructions when you CREATE or ALTER the tables you are using. See for instance MySql 5.0 create indexes

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文