我需要一点帮助来改善以下查询性能
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) |
+----+-------------+-----------------+--------+----------------------------------+---------+---------+-----------------------------------+--------+------------------------------------------------+
答案 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值的临时表上使用原始查询。
第二种选择: 在左连接中为您要比较的每个键创建索引,这样索引就能为您完成工作。
当然,你可以随时结合我建议的两种方法。