使用EXPLAIN输出

时间:2015-06-27 13:40:03

标签: mysql optimization explain

以下查询需要6.6秒才能运行,并产生26行。

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类型,并定义为INDEX。字段forum_id被定义为FOREIGN KEY。

我很乐意找出导致这种令人发指的表现的原因:)

3 个答案:

答案 0 :(得分: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的文件排序。

答案 1 :(得分: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%左右。

答案 2 :(得分:0)

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