这个Mysql SQL Select查询需要33分钟才能执行

时间:2017-07-20 22:39:02

标签: php mysql performance optimization query-optimization

标题说明了一切。你认为有人可以帮我解开这个吗?或者,如果有人可以指出我还有什么可能导致它花费这么多时间。查询大约需要半小时才能运行。写这个的人尝试在循环中执行它,通过从最后一个连接语句中删除表,然后查询每个投票的field.title。我希望将结果带到约5分钟。

一些额外的信息:

查询结果为83,531行

投票表大小为30 MB(261,169行)

SELECT `vote`.`id` `vote_id`, `branch`.`name` `branch`, `brand`.`name` `brand`, DATE(vote.created_at) `date`, HOUR(vote.created_at) `time_hour`,
            MINUTE(vote.created_at) `time_minute`, `vote`.`is_like`, `voter`.`name`, `voter`.`telephone`, `voter`.`email`, popups_votes.title  `popup_title`,
            popups_votes.value  `popup_value`, GROUP_CONCAT(dis.field SEPARATOR '|') `reasons`
            FROM (`vote`)
            LEFT JOIN `voter` ON `voter`.`id` = `vote`.`voter_id`
            LEFT JOIN `device` ON `device`.`id` = `vote`.`device_id`
            LEFT JOIN `branch` ON `branch`.`id` = `device`.`branch_id`
            LEFT JOIN `brand` ON `brand`.`id` = `branch`.`brand_id`
            LEFT JOIN `popups_votes` ON popups_votes.vote_id = vote.id
            LEFT JOIN (SELECT vote_dislike.vote_id `vote_id`, field.title `field` FROM vote_dislike
                    LEFT JOIN branch_dislike_field ON branch_dislike_field.id = vote_dislike.branch_dislike_id
                    LEFT JOIN field ON field.id = branch_dislike_field.field_id) dis
                    ON dis.vote_id = vote.id
            WHERE (vote.device_id in
             (
             Select d.id
             From device d
             WHERE d.branch_id IN (SELECT id FROM branch WHERE brand_id = 7)
             )
             )
             AND (vote.created_at >= FROM_UNIXTIME('$from_time') AND vote.created_at <= FROM_UNIXTIME('$to_time') )
            GROUP BY vote.id

编辑:这是解释{query}输出:

+------+-------------+----------------------+--------+----------------------+-----------+---------+-------------------------------------------+------+----------------------------------------------+
| id   | select_type | table                | type   | possible_keys        | key       | key_len | ref                                       | rows | Extra                                        |
+------+-------------+----------------------+--------+----------------------+-----------+---------+-------------------------------------------+------+----------------------------------------------+
|    1 | PRIMARY     | branch               | ref    | PRIMARY,brand_id     | brand_id  | 4       | const                                     |   20 | Using index; Using temporary; Using filesort |
|    1 | PRIMARY     | d                    | ref    | PRIMARY,branch_id    | branch_id | 4       | river_back.branch.id                      |    1 | Using index                                  |
|    1 | PRIMARY     | vote                 | ref    | device_id,created_at | device_id | 4       | river_back.d.id                           | 1200 | Using where                                  |
|    1 | PRIMARY     | voter                | eq_ref | PRIMARY              | PRIMARY   | 4       | river_back.vote.voter_id                  |    1 |                                              |
|    1 | PRIMARY     | device               | eq_ref | PRIMARY              | PRIMARY   | 4       | river_back.d.id                           |    1 |                                              |
|    1 | PRIMARY     | branch               | eq_ref | PRIMARY              | PRIMARY   | 4       | river_back.device.branch_id               |    1 | Using where                                  |
|    1 | PRIMARY     | brand                | eq_ref | PRIMARY              | PRIMARY   | 4       | river_back.branch.brand_id                |    1 | Using where                                  |
|    1 | PRIMARY     | popups_votes         | ref    | vote_id              | vote_id   | 5       | river_back.vote.id                        |  602 |                                              |
|    1 | PRIMARY     | vote_dislike         | ref    | vote_id              | vote_id   | 4       | river_back.vote.id                        |    1 |                                              |
|    1 | PRIMARY     | branch_dislike_field | eq_ref | PRIMARY              | PRIMARY   | 4       | river_back.vote_dislike.branch_dislike_id |    1 | Using where                                  |
|    1 | PRIMARY     | field                | eq_ref | PRIMARY              | PRIMARY   | 4       | river_back.branch_dislike_field.field_id  |    1 | Using where                                  |
+------+-------------+----------------------+--------+----------------------+-----------+---------+-------------------------------------------+------+----------------------------------------------+

2 个答案:

答案 0 :(得分:2)

您应该检查您选择的所有数据是否已编入索引并且您有外键。

How do MySQL indexes work?

  

基本上,表上的索引就像书中的索引一样(即   名字来自哪里):

     

假设你有一本关于数据库的书,你想找一些   关于存储的信息。没有索引(假设没有其他   您必须浏览页面的帮助,例如目录   一个接一个,直到找到主题(这是一个全表扫描)。上   另一方面,索引有一个关键字列表,所以你可以查阅   索引并查看第113-120,231和354页提到的存储。   然后你可以直接翻到那些页面,而无需搜索(那是   使用索引进行搜索,速度稍快一些。)

Basics of Foreign Keys in MySQL?

  

FOREIGN KEYS只是确保您的数据一致。

     

他们只是在效率方面不改进查询   一些错误的查询失败。

答案 1 :(得分:0)

  • 请勿使用LEFT,除非您希望“正确”的表格中缺少行。

  • 特别是,优化器可能无法从'派生表'开始,因为它隐藏在左侧的右侧。

  • 不要使用IN ( SELECT ... );如果可能,请更改为EXISTS ( SELECT * ...)JOIN

  • 尽量避免JOIN ... GROUP BY造成的“膨胀 - 缩小”。如果可能,请找到感兴趣的ID ,无需需要GROUP BY然后 JOIN到其他表格。

将这些中的许多放在一起,这是否能让您接近所需的结果,至少在获得正确的vote.id值的意义上?

SELECT vote.id
    FROM vote AS v
    JOIN (
        SELECT  vote_dislike.vote_id `vote_id`, field.title `field`
            FROM  vote_dislike AS vd
            LEFT JOIN  branch_dislike_field AS bd
              ON bd.id = vd.branch_dislike_id
            LEFT JOIN  field
              ON field.id = bd.field_id
          ) AS dis  ON dis.vote_id = v.id
    JOIN device AS d ON v.device_id = d.id
    JOIN branch AS b ON d.branch_id = b.id
    WHERE b.brand_id = 7
      AND v.created_at >= ...
      AND v.created_at <= ...

然后:

SELECT lots of stuff
    FROM ( the above query ) AS x
    JOIN vote v  ON x.id = v.id   -- yes, dig back into `vote` for the other stuff
    JOIN voter ...
    JOIN ...

但没有GROUP BY

相关问题