2015-06-27 62 views
0

以下查询需要6.6秒来运行,并产生26行。使用EXPLAIN输出优化缓慢的MySQL查询

EXPLAIN结果是'ref'类型的两个SIMPLE查询,使用键扫描23行和48行。

表f有1000行,表m有42000行。

 
seltype table type keys     key     keylen ref    rows filtered extra 

SIMPLE f  ref PRIMARY,    forum_site_id  4  const   23 100.00 Using where; Using temporary; Using filesort 
        forum_site_id, 
        forums_flag_list_new_posts 

SIMPLE m  ref forum_msg_forum_id, forum_msg_forum_id 5  locali_db.f.id 48 100.00 Using where 
        forum_msg_status, 
        forum_msg_date 

下面是该查询(相当简单的一个):

SELECT 

    m.id AS msg_id, 
    m.public_id AS msg_public_id, 
     more fileds of this table ... 

    f.id AS forum_id, 
    f.public_id AS forum_public_id, 
     more fileds of this table ... 

FROM 

    forum_msgs m 
    INNER JOIN forums f ON 
     m.forum_id = f.id 

WHERE 

    f.site_id = 19 
    AND f.flag_list_new_posts = 1 

    AND m.msg_date >= 1434803744 
    AND m.status <> 11 

ORDER BY 
    m.msg_date DESC 

LIMIT 
    100 

在WHERE和ORDER BY子句是类型INTEGER的和被定义为索引中的所有字段。字段forum_id被定义为FOREIGN KEY。

我会很高兴,找出可能导致令人发指的性能:)

+0

应该避免在第二张桌子上使用。 – Tim3880

回答

0

数据库运行在RDS上,QPS相当高(峰值高达200)。平均而言,这会导致磁盘50 IOP/s。将实例存储类型从磁更改为通用SSD解决了此问题。

0

您的查询基本上是:

SELECT m.*, f.* 
FROM forum_msgs m INNER JOIN 
    forums f 
    ON m.forum_id = f.id 
WHERE f.site_id = 19 AND 
     f.flag_list_new_posts = 1 AND 
     m.msg_date >= 1434803744 AND 
     m.status <> 11 
ORDER BY m.msg_date DESC 
LIMIT 100; 

这表明了以下指标:forums(site_id, flag_list_new_posts, id)forum_msgs(forum_id, msg_date, status)

我不认为有办法绕过order by的文件排序。

+0

在索引中有两次'msg_date'没有任何好处。 –

+0

@RickJames。 。 。我修复了这个索引。 –

0
INDEX(msg_date) 

魔法门招优化与m开始,并避免排序为ORDER BY

提供SHOW CREATE TABLE提问的性能问题时。)

但排序不昂贵的部分。昂贵的部分可能是随机提取到m。显然缓存很冷。

EXPLAIN估计大约1000次读取(23 * 48),但可能严重低估/高估。如果m没有被很好地缓存,那可能是1000个磁盘命中,这很容易花费6.6秒。

如果您使用的是InnoDB,innodb_buffer_pool_size应该是可用 RAM的70%左右。

+0

SHOW CREATE的'forum_msgs名单表中的下列指标: PRIMARY KEY('id') UNIQUE KEY'uniq_public_id'('public_id') KEY'forum_msg_forum_id'('forum_id') KEY'forum_msg_status '('status') KEY'forum_msg_date'('msg_date') KEY'forum_msg_display_number'('display_number') KEY'forum_msg_site_id'('site_id') KEY'forum_msgs_num_clicks'('num_clicks') , KEY'forum_msgs_parent_id'('parent_id') –

+0

您使用的是什么引擎?什么数据类型是'public_id'?那么'f'呢? –