Sql查询优化和调试

时间:2017-10-12 13:36:12

标签: mysql

我正在尝试优化mysql db中的sql查询。尝试了不同的重写方式,添加/删除索引,但似乎没有什么能减少负载。也许我错过了什么。 查询:

select co.country_name as state, ci.city_name as city, ci.city_id, ci.country_id,
                        count(l.id) as num  
                        FROM cities ci 
                        INNER JOIN countries co ON (ci.country_id = co.country_id)
                        INNER JOIN dancers l ON (l.city_id = ci.city_id AND l.closed = 0 AND l.approved = 1 )
                        WHERE 1 AND ci.main=1                   
                        GROUP BY ci.city_id
                        ORDER BY city 

持续时间:2.01秒 - 2.20秒 优化查询:

    select co.country_name as state, ci.city_name as city, ci.city_id, ci.country_id, count(l.id) as num from 
(select ci1.city_name, ci1.city_id, ci1.country_id from cities ci1 
where ci1.main=1) as ci 
INNER JOIN countries co ON (ci.country_id = co.country_id) 
INNER JOIN dancers l ON (l.city_id = ci.city_id AND l.closed = 0 AND l.approved = 1 ) GROUP BY ci.city_id ORDER BY city

持续时间:0.82秒 - 0.90秒

但是我觉得这个查询可以进一步优化但是没有让ideea如何优化它。有3个表

Table 1 : countries ( country_id, country_name)
Table 2 : cities ( city_id, city_name, main, country_id)
Table 3 : dancers ( id, country_id, city_id, closed, approved) 

我正在努力让所有拥有main = 1的城市和每个城市都计算加入国家/地区的所有城市的个人资料以获取country_name。

欢迎任何想法,谢谢。

稍后编辑: - 第一次查询解释

+----+-------------+-------+-------------+---------------------------------------------------------------------+-----------------+---------+------------------+-------+--------------------------------------------------------------------------------+
| id | select_type | table |    type     |                            possible_keys                            |       key       | key_len |       ref        | rows  |                                     Extra                                      |
+----+-------------+-------+-------------+---------------------------------------------------------------------+-----------------+---------+------------------+-------+--------------------------------------------------------------------------------+
|  1 | SIMPLE      | l     | index_merge | city_id,closed,approved,city_id_2                                   | closed,approved |     1,2 | NULL             | 75340 | Using intersect(closed,approved); Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | ci    | eq_ref      | PRIMARY,state_id_2,state_id,city_name,lat,city_name_shorter,city_id | PRIMARY         |       4 | db.l.city_id     |     1 | Using where                                                                    |
|  1 | SIMPLE      | co    | eq_ref      | PRIMARY                                                             | PRIMARY         |       4 | db.ci.country_id |     1 | Using where                                                                    |
+----+-------------+-------+-------------+---------------------------------------------------------------------+-----------------+---------+------------------+-------+--------------------------------------------------------------------------------+

第二个查询说明:

+----+-------------+------------+------+-----------------------------------+-------------+---------+------------------+-------+------------------------------------+
| id | select_type |   table    | type |           possible_keys           |     key     | key_len |       ref        | rows  |               Extra                |
+----+-------------+------------+------+-----------------------------------+-------------+---------+------------------+-------+------------------------------------+
|  1 | PRIMARY     | co         | ALL  | PRIMARY                           | NULL        | NULL    | NULL             |    51 | Using temporary; Using filesort    |
|  1 | PRIMARY     | <derived2> | ref  | <auto_key1>                       | <auto_key1> | 4       | db.co.country_id |   176 | Using where                        |
|  1 | PRIMARY     | l          | ref  | city_id,closed,approved,city_id_2 | city_id_2   | 4       | ci.city_id       |    44 | Using index condition; Using where |
|  2 | DERIVED     | ci1        | ALL  | NULL                              | NULL        | NULL    | NULL             | 11765 | Using where                        |
+----+-------------+------------+------+-----------------------------------+-------------+---------+------------------+-------+------------------------------------+

@used_by_already查询说明:

+----+-------------+------------+-------------+-----------------------------------+-----------------+---------+------------------+-------+--------------------------------------------------------------------------------+
| id | select_type |   table    |    type     |           possible_keys           |       key       | key_len |       ref        | rows  |                                     Extra                                      |
+----+-------------+------------+-------------+-----------------------------------+-----------------+---------+------------------+-------+--------------------------------------------------------------------------------+
|  1 | PRIMARY     | co         | ALL         | PRIMARY                           | NULL            | NULL    | NULL             |    51 | NULL                                                                           |
|  1 | PRIMARY     | <derived2> | ref         | <auto_key0>                       | <auto_key0>     | 4       | db.co.country_id |   565 | Using where                                                                    |
|  2 | DERIVED     | l          | index_merge | city_id,closed,approved,city_id_2 | closed,approved | 1,2     | NULL             | 75341 | Using intersect(closed,approved); Using where; Using temporary; Using filesort |
|  2 | DERIVED     | ci1        | eq_ref      | PRIMARY,state_id_2,city_id        | PRIMARY         | 4       | db.l.city_id     |     1 | Using where                                                                    |
+----+-------------+------------+-------------+-----------------------------------+-----------------+---------+------------------+-------+--------------------------------------------------------------------------------+

1 个答案:

答案 0 :(得分:1)

我建议你试试这个:

SELECT
      co.country_name AS state
    , ci.city_name    AS city
    , ci.city_id
    , ci.country_id
    , ci.num
FROM (
      SELECT
            ci1.city_id
          , ci1.city_name
          , ci1.country_id
          , COUNT(l.id) AS num
      FROM cities ci1
      INNER JOIN dancers l ON l.city_id = ci1.city_id
            AND l.closed = 0
            AND l.approved = 1
      WHERE ci1.main = 1
      GROUP BY
            ci1.city_id
          , ci1.city_name
          , ci1.country_id
      ) AS ci
INNER JOIN countries co ON ci.country_id = co.country_id
;

如果需要,您可以提供解释计划输出以供进一步分析。在优化知道哪些索引存在并让他解释计划时,是必需品。

不是,MySQL确实允许非标准的GROUP BY语法(其中只有group by子句中包含选择列表中的一个或一些列)。 在最新版本的MySQL中,GROUP BY的默认行为已更改为SQL标准语法(其中选择列表中的所有“非聚合”列必须包含在group by子句下)。虽然现有查询使用非标准组语法,但此处提供的查询不符合。

相关问题