0

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

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) |
+----+-------------+-----------------+--------+----------------------------------+---------+---------+-----------------------------------+--------+------------------------------------------------+
4

2 回答 2

1

如果您没有在 dle_playerfiles 的 post_id 上放置索引,则在其上放置索引。
如果您已经在其上放置了索引,那么在最后加入的查询中写入“使用索引”,如下所示:

 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 行。

于 2013-09-16T08:47:34.660 回答
0

我可以建议两个替代方案来解决这个问题。

第一种选择:

为您与 LEFT 连接比较的键创建一个仅包含非 NULL 值的临时表。

像这样的东西:

select *
into #dle_post_plus 
where pause_postid is not null

对所有三个表执行此操作。

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

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

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

于 2013-09-16T08:45:17.370 回答