如何优化这个SQL查询(内连接)

时间:2015-10-06 17:03:32

标签: mysql optimization query-optimization

无论如何都要优化这个查询。执行时间超过40秒。我尝试了很多方法,比如创建索引。这有点帮助。但查询时间太长。

 SELECT b.id,
   Count(DISTINCT a.id, c.chapters_id) AS pct,
   Count(DISTINCT e.id)                 AS eCount,
   Count(DISTINCT f.id)                 AS fCount,
   Count(DISTINCT d2.id)                 AS d2Count,
   b.NAME,
   e.NAME,
   e.address2,
   f.NAME,
   d2.is_active
FROM   tableA a
       INNER JOIN tableB b
               ON a.modules_id = b.id
       INNER JOIN tableC c
               ON a.modules_id = c.modules_id
       INNER JOIN tableD d1
               ON d1.id = b.store_users_id 
       INNER JOIN tableD d2
               ON d2.id = a.store_users_id
       INNER JOIN tableE e
               ON e.id = d2.stores_id
       INNER JOIN tableF f
               ON e.city = f.id
WHERE  b.type IN( 1, 2, 4 )
       AND b.organizations_id = 156
       AND b.is_enable = true
GROUP  BY b.NAME,b.id

EXPLAIN

   +----+-------------+-------+--------+-----------------------------------------------------------------------------------------------------+-----------------------------+---------+--------------------------+------+---------------------------------------+
| id | select_type | table | type   | possible_keys                                                                                       | key                         | key_len | ref                      | rows | Extra                                 |
+----+-------------+-------+--------+-----------------------------------------------------------------------------------------------------+-----------------------------+---------+--------------------------+------+---------------------------------------+
|  1 | SIMPLE      | b     | range  | PRIMARY,fk_modules_organizations1,fk_modules_store_users1,sort_modules_name,wh_modules_type,new_idx | new_idx                     | 9       | NULL                     |  160 | Using index condition; Using filesort |
|  1 | SIMPLE      | c     | ref    | fk_module_chapters_modules1                                                                         | fk_module_chapters_modules1 | 4       |         b.id             |    1 | NULL                                  |
|  1 | SIMPLE      | d1    | eq_ref | PRIMARY                                                                                             | PRIMARY                     | 4       |         b.store_users_id |    1 | Using index                           |
|  1 | SIMPLE      | a     | ref    | store_users_id_UNIQUE,fk_user_modules_store_users1,fk_user_modules_modules1                         | fk_user_modules_modules1    | 4       |         b.id             |  149 | NULL                                  |
|  1 | SIMPLE      | d2    | eq_ref | PRIMARY,fk_store_users_stores1                                                                      | PRIMARY                     | 4       |         a.store_users_id |    1 | NULL                                  |
|  1 | SIMPLE      | e     | eq_ref | PRIMARY,Stores-Cities                                                                               | PRIMARY                     | 4       |        d2.stores_id      |    1 | Using where                           |
|  1 | SIMPLE      | f     | eq_ref | PRIMARY                                                                                             | PRIMARY                     | 4       |         e.city           |    1 | NULL                                  |
+----+-------------+-------+--------+-----------------------------------------------------------------------------------------------------+-----------------------------+---------+--------------------------+------+---------------------------------------+

1 个答案:

答案 0 :(得分:0)

这可能对某些人有所帮助:

INDEX(organizations_id, is_enable, type) -- on b

因为你说COUNT(DISTINCT...),它闻起来像JOINs正在爆炸行数,然后你DISTINCTifying回到他们应该的位置。一种方法是在没有最终SELECT COUNT(*) FROM ... JOIN ...的情况下执行GROUP BY。如果这是一个比任何表格大得多的数字,那么你有这个经典问题。

有时解决方案是用

替换JOIN
SELECT  ...,
        ( SELECT COUNT(*) FROM x ... )  AS x_ct,  -- instead of `JOIN x`
        ...