使用JOIN查询需要花费太多时间

时间:2013-09-16 08:09:32

标签: mysql performance join

我需要一点帮助来改善以下查询性能

SELECT * 
FROM   dle_pause 
       LEFT JOIN dle_post_plus 
              ON ( dle_pause.pause_postid = dle_post_plus.puuid ) 
       LEFT JOIN dle_post 
              ON ( dle_post_plus.news_id = dle_post.id ) 
       LEFT JOIN dle_playerfiles 
              ON ( dle_post.id = dle_playerfiles.post_id ) 
WHERE  pause_user = '2'; 

问题在于第三次加入需要3 rows in set (0.35 sec)。其中一行没有dle_post.id = dle_playerfiles.post_id,因此它会扫描整个表格。

看起来我有所有需要的索引

+----+-------------+-----------------+--------+----------------------------------+---------+---------+-----------------------------------+--------+------------------------------------------------+
| id | select_type | table           | type   | possible_keys                    | key     | key_len | ref                               | rows   | Extra                                          |
+----+-------------+-----------------+--------+----------------------------------+---------+---------+-----------------------------------+--------+------------------------------------------------+
|  1 | SIMPLE      | dle_pause       | ALL    | pause_user                       | NULL    | NULL    | NULL                              |      3 | Using where                                    |
|  1 | SIMPLE      | dle_post_plus   | ref    | puuid                            | puuid   | 36      | func                              |      1 | Using where                                    |
|  1 | SIMPLE      | dle_post        | eq_ref | PRIMARY                          | PRIMARY | 4       | online_test.dle_post_plus.news_id |      1 | NULL                                           |
|  1 | SIMPLE      | dle_playerFiles | ALL    | ix_dle_playerFiles__post_id_type | NULL    | NULL    | NULL                              | 131454 | Range checked for each record (index map: 0x2) |
+----+-------------+-----------------+--------+----------------------------------+---------+---------+-----------------------------------+--------+------------------------------------------------+

2 个答案:

答案 0 :(得分:1)

如果你没有在dle_playerfiles的post_id上放置索引,那么就把索引放在上面 如果你已经在其上放了一个索引,那么在你的查询中,最后一次加入写'use index',如下所示:

 SELECT * 
  FROM 
     dle_pause 
   LEFT JOIN dle_post_plus 
          ON ( dle_pause.pause_postid = dle_post_plus.puuid ) 
   LEFT JOIN dle_post 
          ON ( dle_post_plus.news_id = dle_post.id ) 
   LEFT JOIN dle_playerfiles **use index(post_id)**
          ON ( dle_post.id = dle_playerfiles.post_id ) 
   WHERE 
     pause_user = '2';

这也将使用第四个表的索引。现在你的解释显示它没有在第四个表上使用任何索引,因此扫描131454行。

答案 1 :(得分:0)

我可以建议两种解决方法。

第一种选择:

创建一个临时表,其中只包含与LEFT join比较的键的非NULL值。

这样的事情:

select *
into #dle_post_plus 
where pause_postid is not null

为所有三个表做。

然后在不包含NULL值的临时表上使用原始查询。

第二种选择: 在左连接中为您要比较的每个键创建索引,这样索引就能为您完成工作。

当然,你可以随时结合我建议的两种方法。