使用JOINS和子查询优化查询

时间:2016-04-04 15:46:15

标签: mysql subquery query-optimization

我想加快我的一个较慢的查询。

问题是我无法访问子查询中的外部列值。

我有什么:

SELECT r.id AS room_id, r.room_name, coalesce(d.score,0) AS total_messages, d.latest 
FROM cf_rooms_time_frames tf
INNER JOIN cf_rooms r on r.id = tf.room_id 
INNER JOIN(
    SELECT cf.room_id, count(*) as score, max(cf.id) as latest 
    FROM cf_rooms_messages cf 
    WHERE EXISTS( 
        SELECT NULL FROM cf_rooms_time_frames tf 
        WHERE tf.start <= cf.id AND ( tf.end IS NULL OR tf.end >= cf.id ) 
        AND tf.room_id = cf.room_id AND tf.uid = 8
        )
    GROUP BY cf.room_id  
    ORDER BY latest 
    DESC ) d on d.room_id = r.id 

WHERE tf.uid = 8
ORDER BY coalesce(latest, score) DESC LIMIT 0, 20

我想要的是什么:

SELECT r.id AS room_id, r.room_name, coalesce(d.score,0) AS total_messages, d.latest 
FROM cf_rooms_time_frames tf
INNER JOIN cf_rooms r on r.id = tf.room_id 
INNER JOIN(
    SELECT cf.room_id, count(*) as score, max(cf.id) as latest 
    FROM cf_rooms_messages cf 
    /* line added here */
    WHERE cf.room_id = tf.room_id
    /* */
    AND EXISTS( 
        SELECT NULL FROM cf_rooms_time_frames tf 
        WHERE tf.start <= cf.id AND ( tf.end IS NULL OR tf.end >= cf.id ) 
        AND tf.room_id = cf.room_id AND tf.uid = 8
        )
    GROUP BY cf.room_id  
    ORDER BY latest 
    DESC ) d on d.room_id = r.id 

WHERE tf.uid = 8
ORDER BY coalesce(latest, score) DESC LIMIT 0, 20

我认为标记解释了查询的作用。

它搜索给定用户的“聊天室”,并按最后一条消息对其进行排序,获取在给定范围(时间帧)内的ids总消息数,以及最后一条消息ID。

我不知道为什么,但是第一个查询返回chatmessage表中的所有行(cf),如果我可以信任EXPLAIN。它提供了正确的结果,但在巨大的桌子上有点慢。

我使用“硬编码”room_id测试了第二个,这个非常快,并没有“触及”整个表格。

0 个答案:

没有答案