以下查询需要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。
我很乐意找出导致这种令人发指的表现的原因:)
答案 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解决了这个问题。