2017-10-12 63 views
1

我想优化mysql数据库中的sql查询。尝试了重写它的不同方式,添加/删除索引,但似乎没有减少负载。也许我错过了一些东西。 查询: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.01sec - 2.20sec 优化查询:

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.82sec - 0.90sec

但我觉得这种查询可以更加优化但没有得到如何优化它的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) 

我试图让所有这些都主要= 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                 | 
+----+-------------+------------+-------------+-----------------------------------+-----------------+---------+------------------+-------+--------------------------------------------------------------------------------+ 
+0

请包括解释计划输出(作为文本) –

+0

我编辑的第一篇文章与解释 –

+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子句下)。虽然您的现有查询按语法使用非标准组,但此处提供的查询不符合规定。

+0

你有没有得到这个查询变体的解释计划? –

+0

在主体中添加了对您的查询的解释 –